Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Давай разберемся, как вытащить исходники из «скомпилированного» скрипта AutoIt, обойти обфускацию и снять триальные ограничения без пересборки проекта. Я покажу, как работает декомпилятор myAutToExe, где скрыты строки и как подловить ключевую переменную, чтобы обмануть проверку регистрации, — по шагам, от реверса до финального патча.
Сегодня мы будем сочетать приятное с полезным, а именно погрузимся в две наши любимые темы — разные экзотические интерпретаторы и деобфускация. Я уже достаточно злословил на тему того, сколько в последнее время понапридумывали средств разработки для чайников, чтобы каждый школьник после просмотра ознакомительного тиктоковского ролика мог закодить свою первую программу.
Наверное, ты удивился, почему я до сих пор не упоминал такое распространенное условно‑бесплатное поделие, как AutoIt? Судя по всему, он задумывался как мечта любой дрессированной обезьяны — ничего не надо программировать, просто вози мышкой по экрану и тыкай по кнопкам, все твои действия автоматически скриптуются, причем совершенно безвозмездно, то есть даром. Для тех, кто чуть поумнее, наскоро придумали урезанную версию бейсика для добавления в скрипты простенькой логики.
Дальше, по мере роста популярности технологии, ее создатели пошли по накатанной схеме — придумали механизм компоновки из простецких текстовых скриптов исполняемых файлов, и вот уже целые коммерческие проекты пишутся исключительно на AutoIt. Причем изначально в политике конторы сохранялось некое фриварно‑опенсорсное фрондерство: пакет, помимо «компилятора» Aut2Exe, преобразовывающего скрипт в исполняемый модуль, содержал «декомпилятор», проворачивающий фарш назад, — Exe2Aut.
Однако с версии 3.2.5.1 эти вредные веяния упразднили и теперь грозят всяческими карами наглецам, посмевшим заикнуться о восстановлении кода из «скомпилированного» исполняемого файла. Конечно же, угрозами дело не ограничилось — была предпринята и программная защита исходного кода (местами довольно забавная): прекомпиляция исходников в байт‑код, который потом упаковывали, зашифровывали и даже навешивали сверху UPX, а кроме того, использовали весьма примитивную обфускацию. Естественно, такая защита эффективна исключительно от честных людей, точнее, от школьников, незнакомых с основами реверс‑инжиниринга.
Я давно хотел написать разбор одного из таких проектов, но никак не мог найти подходящий коммерческий продукт. И вот кандидат на роль подопытного кролика наконец отыскался. Итак, у нас имеется некий программный пакет автоматизации, записывающий и воспроизводящий ряд действий пользователя с клавиатурой и мышью. Detect It Easy красноречиво указывает на его происхождение.
Exeinfo PE более конкретно называет версию — AutoIt v3.3.13.15. Пакет работает, но без регистрации существует ряд раздражающих ограничений: при определенных действиях программа выдает сообщения вида «Unregistered version can not …, to register?» с предложением, понятное дело, зарегистрироваться.
Лицензионный ключ программа запрашивает на сайте разработчика, там же этот ключ и валидирует, что дополнительно характеризует авторов с не очень хорошей стороны. Раз так, попробуем сами вытащить исходники из исполняемого файла. Поскольку версия нашего AutoIt выше 3.2.5.1, штатного декомпилятора для нее не существует.
По счастью, имеются и сторонние декомпиляторы, и деобфускаторы AutoIt, и Exeinfo PE даже указывает нам на них: это Exe2Aut decomp. v0.10 2014 и AU3Stripper v19.x 2019 or myAutToExe 2.15 [email protected].
Первая ссылка уже мертва, а со второй явно что‑то не то, однако проект myAutToExe вполне существует и поддерживается на GitHub. Можно нагуглить еще, к примеру, питоновский скрипт AutoIt-Ripper, но нам вполне подходит и myAutToExe — он самый актуальный, да еще и со множеством заявленных дополнительных фич, поэтому им и воспользуемся.
Действительно, этот инструмент восстановил нам исходный au3-файл, сэкономив кучу времени и нервов на разбор виртуальной машины и системы команд AutoIt, которых мы на этот раз касаться не будем. Возможно, у нас когда‑нибудь появится задача, для которой это будет необходимо, но пока что для дальнейших действий вполне достаточно и восстановленного кода. Желающие могут самостоятельно углубиться в эту тему, более детально исследовав исходники приведенных выше гитхабовских проектов.
У нас же, даже несмотря на наличие восстановленного кода, веселье только начинается. При первом взгляде становится очевидно, что полученный код совершенно нечитаем.
Начисто отсутствуют имена идентификаторов, численные и строковые константы. Судя по обилию функций EXECUTE()
, вероятно, зашифрованы особо критичные фрагменты кода — налицо явная обфускация с целью осложнить нам жизнь. Причем обфускация какая‑то самописно‑кастомная, поскольку в использованном нами myAutToExe деобфускация известных инструментов заявлена прямо «из коробки». В readme.txt
даже перечислен список поддерживаемых обфускаторов:
Supported Obfuscators:
‘Jos van der Zande AutoIt3 Source Obfuscator v1.0.14 [June 16, 2007]’ ,
‘Jos van der Zande AutoIt3 Source Obfuscator v1.0.15 [July 1, 2007]’ ,
‘Jos van der Zande AutoIt3 Source Obfuscator v1.0.20 [Sept 8, 2007]’ ,
‘Jos van der Zande AutoIt3 Source Obfuscator v1.0.22 [Oct 18, 2007]’ ,
‘Jos van der Zande AutoIt3 Source Obfuscator v1.0.24 [Feb 15, 2008]’ ,
‘EncodeIt 2.0’ and
‘Chr() string encode’
Причем содержащиеся в примерах обфусцированные файлы этим самым Jos van der Zande AutoIt3 Source Obfuscator до боли напоминают наш код, но что‑то неуловимое мешает myAutToExe корректно его детектировать и деобфусцировать. Не будем искать ответ на вопрос, что именно и как починить myAutToExe, — у нас сейчас есть конкретная цель, и нет смысла отвлекаться на побочные квесты. Попробуем придать программе читабельности своими руками.
Благо мы уже изрядно поднаторели в гораздо более мрачной деобфускации. В качестве примеров можешь посмотреть другие мои статьи:
Вдобавок умные люди уже давно занимаются делом деобфускации скриптов AutoIt и пишут об этом статьи. В общем, как говорится, глаза боятся, а руки делают.
Начнем с восстановления текстовых строк. По обилию в восстановленном коде присваиваний выражений вида A2E00001A18($OS[...])
можно предположить, что строковые константы каким‑то образом закодированы через эти функции и массив. Находим функцию A2E00001A18
в самом конце кода:
FUNC A2E00001A18($A2E00001A18) LOCAL $A2E00001A18_ FOR $X=1 TO STRINGLEN($A2E00001A18)STEP 2 $A2E00001A18_&=CHR(DEC(STRINGMID($A2E00001A18,$X,2))) NEXT RETURN $A2E00001A18_ ENDFUNC
Ничего сложного, типичная криптография для младших школьников: каждый символ закодирован двумя Hex-символами своего 8-битного шестнадцатеричного кода. Осталось понять, как формируется огромный (несколько тысяч элементов) массив исходных строк для этой функции $OS[]
. Если глянуть на предыдущий скриншот, то становится очевидно, что его заполняет функция A2E00001A18_()
, тоже расположенная в конце кода.
В ней также нет ничего сложного: она зачем‑то целых пять раз подряд сохраняет в файл временного каталога со случайным названием (генерируемым функцией a2e00001a18x_()
) огромный массив текстовых данных, захардкоженный в предшествующей функции _igrf4d27dqc()
. Немного смущают вот эти «зашифрованные» строки кода:
Global $a2e00001a18, $os = Execute(BinaryToString("0x457865637574652842696E617279746F737472696E672827...
И вот такие:
Execute(BinaryToString("0x457865637574652842696E617279746F737472696E672827307834353738363536333735373...
Первая из них заполняет искомый массив $OS
, но, судя по использованию функции BinaryToString()
, других криптоалгоритмов автор обфускатора пока не выучил, поэтому пишем простенькую программку на шарпе и раскодируем первую строку:
string newline = "";for (int j = 0; j < sline.Length; j += 2){ string charcode = sline.Substring(j, 2); try { byte bt = Convert.ToByte(charcode, 16); newline += (char)(bt); } catch (Exception e) { break; }}
Источник: xakep.ru