CODE PERVERTOR
                               ~~~~~~~~~~~~~~

 Выдержка из курса английского языка для самых маленьких:
 to PERVERT:
 1) извращать, фальсифицировать
 2) портить, развращать, разлагать, совращать

     Все  вы  слышали про ОБРАТНОЕ ПРОЕКТИРОВАНИЕ (reverse engineering), то
 бишь  про  дисасемблирование  программы,  изменение  логики  и последующую
 компиляцию.  И  все  слышали  про  некое  жалкое  подобие  реверсирования,
 выполняющееся   автоматически,   а  именно  --  про  ПЕРМУТАЦИЮ,  то  есть
 перестройку  вирусного  кода  на  уровне  ассемблерных инструкций, с целью
 затруднить  его  анализ  и детектирование. Очевидно, что явным эффектом от
 пермутации  будет постоянное изменение некоторой контрольной суммы вируса,
 и,   как   следствие   --   усложнение   алгоритма  и  увеличение  времени
 детектирования.
     А  что  будет  если  пермутации  подвергнуть  не  вирусный  код, а код
 некоторой неизвестной программы? Очевидно, что с нашими ресурсами (времени
 и объема памяти) сделать это невозможно. Дело в том, что пермутация вируса
 --  уже  весьма  сложный  процесс,  который  становится  реальным  за счет
 специальных   ограничений,  накладываемых  на  вирусный  код.  О  коде  же
 неизвестной программы почти ничего сказать нельзя.
     Поэтому  мы упрощаем алгоритм модификации кода насколько это возможно,
 и  приходим  к следующей концепции: все изменения локальны. Изменять можно
 только  те инструкции, про которые известно, что их совершенно точно можно
 изменять  и  на что. Никаких дополнительных "мусорных" инструкций; никакой
 перестановки  блоков,  никаких  инвертирований условных переходов и т.п. И
 тогда   остается  только  ЗАМЕНА  и  ПЕРЕСТАНОВКА.  Причем  замена  должна
 производится  на  инструкции  (или  группы оных) той же длины, выполняющие
 абсолютно  те  же  действия,  а  перестановка  не  должна  никак влиять на
 алгоритм работы.
     Теперь   рассмотрим  какую-нибудь  программу.  В  ней  например  могут
 использоваться  инструкции  вида  MOV  R1,R2, каждая из которых может быть
 заменена  на  PUSH  R2/POP R1, или инструкции вида MOV ESP, EBP & POP EBP,
 которые  могут  быть  заменены  на  LEAVE,  и так далее. Применяя подобные
 изменения  к коду, получаем файл измененный всего лишь в некоторых байтах,
 но работающий так же.
     Что это даст на практике? А на практике это даст изменение контрольной
 суммы  файла.  И как результат, если этот файл был вирусом или трояном, он
 перестанет детектироваться антивирусом. А если файл был упакован, например
 UPX-ом,  то  изменится  сигнатура  распаковщика и антивирус не сможет этот
 файл распаковать, со всеми последствиями.
     Кроме   замены   инструкций   существует   другая   интересная  мысль,
 позволяющая   весьма   сильно   изменять  файл  без  особых  трудов.  Идея
 заключается  в следующем: выбираем в программе случайную инструкцию длиной
 более  4-х  байт,  проверяем,  чтобы  она не имела относительного смещения
 (jmp,call,jcc,...)  и  "выносим"  эту  инструкцию  в  неиспользуемое место
 программы, вставляя до и после нее связующие jmp-ы.
     Теперь  о  проблемах.  Одна проблема заключается в том, чтобы изменять
 достаточно  большое  количество  инструкций, тем самым повышая вероятность
 попадания  хотя  бы  одной  измененной  инструкции  в  участок, проверямый
 контрольной  суммой.  Совсем  другая,  и серьезная проблема, заключается в
 выделении  в  испольняемом  файле  кода. Ибо если мы случайно изменим хоть
 один  байт  данных,  программа скорее всего зависнет. При всем этом код, в
 котором  мы будем проводить изменения должен идти сразу после точки входа,
 так как именно там чаще всего просчитываются контрольные суммы.
     Выделение кода удобно проводить помечая инструкции одну за другой. Для
 такого   примитивного   анализа   файла   достаточно   дисассемблера  длин
 инструкций.
     Короче   говоря,   почти   все  описанные  выше  акты  вандализма  над
 исполняемым кодом реализует программа CODE PERVERTOR.