
IDA Python-скрипт для деобфускации DLL-инжектора Astaroth/Guildma
IDA Python-скрипт для деобфускации DLL-инжектора Astaroth/Guildma
При попытке проанализировать DLL-инжектор из недавней кампании Astaroth/Guildma (спасибо этому дневнику от SANS ISC), я столкнулся с действительно раздражающей попыткой обфускации.
Функция (которую я назвал time_waster_3000 на изображении ниже) вызывается более 1000 раз (!!!) по всей DLL. Эта функция принимает шесть жестко заданных строк в качестве аргументов, а также случайный word. Сама функция — это кроличья нора арифметики, которая не служит никакой практической цели, насколько я мог судить (кроме траты времени реверсера). Вот как выглядит DLLEntry с этими раздражающими вызовами:
Цель этого IDA Python-скрипта — скрыть все блоки кода, которые содержат вызов этой мусорной функции, а также её аргументы. Вот как выглядит DLLEntry после запуска скрипта:
Скрипт работает путем поиска вызова функции-заполнителя, представленного в скрипте как call sub_CHANGEME. Поэтому вам нужно переименовать его в скрипте, указав имя функции, найденное в анализируемом сэмпле. Например, измените idc.print_operand(x, 0) == 'sub_CHANGEME' на idc.print_operand(x, 0) == 'sub_431000'.
Я решил перебирать инструкцию call sub_CHANGEME вместо инструкций передачи аргументов. Причина проста: жестко заданные строки присутствуют в нескольких местах двоичного файла; поэтому при поиске по инструкциям push, использующим смещения этих строк, скрипт не находил все экземпляры этих мусорных данных.
Раньше скрипт скрывал каждый экземпляр передачи аргументов и вызова функции-заполнителя как один свернутый блок. Поскольку функция вызывается несколько раз подряд, это приводило к огромным пустым областям в представлении дизассемблирования. Я обновил скрипт, чтобы он скрывал последовательные экземпляры этого заполнения в одном свернутом блоке, что действительно улучшает читаемость.