• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья Avira – heuristic disasm

Ar3s

Старожил форума
Легенда
Регистрация
30.12.2004
Сообщения
3 357
Реакции
1 404
Avira.png
Вступление
1. Поиск имени нужного детекта в модулях авиры
2. Поиск нужной проверки от антивируса
3. Анализ проверяемых флагов
Заключение

Вступление
Приветствую. Эта статья будет посвящена самому неадекватному антивирусу – авире. Мне всегда было интересно, как же она умудряется отличать вирус от невируса, какие критерии она использует. В этой статье я покажу, как нужно ее реверсить. Некоторые моменты будут озвучены просто как факт, я не буду рассказывать, как я к ним пришел – я просто этого не помню. Также хочу заранее сказать, что я не реверсер, поэтому многие вещи, возможно, я делал не совсем оптимально. Итак, приступим.

1. Поиск имени нужного детекта в модулях авиры

Для анализа нам потребуются IDA Pro с HexRays, OllyDbg, возможно PE Tools. Исследование будет проводиться на примере одного из моих файлов. Назовем его sample.exe. Проверяем его авирой – получаем TR/Crypt.XPACK.Gen2.
16187781.png


Очевидно, чтобы определить нужные нам признаки, нужно найти эту строку в авире, а потом проанализировать код, который к ней обращается.

Весь код анализатора, который нам нужен, находится в библиотеке aeheur.dll. Не буду рассказывать, как я это узнал – это долго и не имеет никакого значения. Загружаем указанную библиотеку в IDA Pro и через поиск (ALT+T) пытаемся найти "TR/Crypt.XPACK.Gen2".

72591147.png


Поиск не дает результатов. Что ж, значит переходим во вкладку Strings (Shift+F12) и начинаем просматривать строки – вдруг найдутся похожие или аналогичные имена, ну или просто что-то интересное.

48958071.png


И что мы видим – очень много переменных, которые напоминают текст, причем однотипный, но нечитаемый. Логично предположить, что это зашифрованный текст. Осталось выяснить, по какому алгоритму он был зашифрован. Я сделал так: выбирал строки наугад и смотрел, каким функциям они передаются. Я очень долго перебирал эти функции, и среди них мне попалась функция расшифровки. Оказалось, что все эти строки зашифрованы обычным XOR с ключом 0х38. Чтобы упростить нам задачу в дальнейшем, создаем скриптовый файл для IDA Pro avira_decrypt.idc с таким содержанием (он нам еще не раз пригодится):

Код:
static main(void){
  auto i;
  i = ScreenEA();
  while (Byte(i) != 0x00){
    PatchByte(i,Byte(i)^0x38);
    i = i+1;
  }
}

Итак, теперь мы знаем, как спрятаны строки. Чтобы найти нужную нам строку в авире, нужно зашифровать ее, а потом искать в уже зашифрованном виде. Для этого я написал утилиту, которая обычный текст зашифровывает по такому же алгоритму, а потом сохраняет в шестнадцатеричном виде. Написание такой утилиты я оставляю за Вами. Итак, берем строку "TR/Crypt.XPACK.Gen2", применяем к каждому байту XOR с ключом 0х38, переводим в текстовый вид. Получаем такую строку: "6C 6A 17 7B 4A 41 48 4C 16 60 68 79 7B". Забегая вперед, скажу, что индекс 2 в конце строки авира не хранит вместе со строкой, она добавляет его кодом. Поэтому обрезаем нашу строку на 1 байт, получаем "6C 6A 17 7B 4A 41 48 4C 16 60 68 79". Именно ее мы будем искать в нашей длл. Для этого переходим в IDA Pro на вкладку IDA View-A, открываем бинарный поиск (ALT+B) и вбиваем зашифрованную строку

37996901.png


Отлично, строка найдена. IDA Pro перебрасывает нас как раз на нее.

86782371.png


Теперь, для нашего удобства, строку неплохо бы расшифровать. Помните наш скрипт? Ставим курсор на начало строки и запускаем наш скрипт. Для первого запуска скрипта нужно нажать ALT+F7 и выбрать файл скрипта. Сразу получаем расшифрованную строку. Чтобы было еще удобнее, не убирая с нее курсор, нажимаем A – IDA Pro даст полноценное имя нашей переменной

35441213.png


2. Поиск нужной проверки от антивируса

Первая часть нашего исследования завершена – у нас есть имя детекта. Осталось самое сложное – проанализировать код и флаги, которые используют этот детект. Не снимая курсор со строки, нажимаем CTRL+X, чтобы увидеть, откуда идут ссылки на эту строку

63310361.png


Да, друзья, искомый нами детект присваивается в десятках мест! И нам нужно найти именно то единственное, где срабатывает проверка. Выхода нет – переходим по первой ссылке и оказываемся в незнакомой функции. Если нажмем F5, HexRays покажет нам С-подобный код функции. Много непонятного, правда?

Я опять вынужден пропустить значительную часть своих исследований, т.к. это все долго и нудно. HexRays пока можно закрыть, он нам не нужен. Перед нами сейчас стоит комплексная задача – сначала найти функцию проверки, которая срабатывает на наш файл. Потом найти внутри этой функции нужную проверку (а их очень много для каждого из детектов). И только после этого можно смотреть на конкретные флаги, которые сравнивает Avira.

Итак, сейчас мы находимся внутри функции, которая дает один из детектов с нужным нам именем. Нажимаем CTRL+P – появляется окно со списком функций. Просто жмем Enter.

99107208.png


Так мы попадаем к началу функции, в которой мы были (листать колесиком мышки было бы слишком долго). Жмем CTRL+X и снова Enter – попадаем в то место, откуда вызывается наша проверка. Обратите внимание на однотипный код – вызов функции, сравнение с 0. Если не 0, тогда вызывается следующая функция. Если 0, тогда на выход. Это вызываются подряд проверки для самых разных детектов. Следовательно, если функция возвращает 0 – файл признан вирусом, если не 0 – файл чист.

94164256.png


Кстати, можем переименовать нашу функцию, чтобы было удобнее читать. Ставим курсор на нашу функцию, нажмем N, вводим имя.

27971935.png


81706089.png


Итак, что мы имеем – огромное количество функций с огромным количеством проверок внутри каждой. Как найти нужную нам? В этом нам поможет отладчик. Для начала несколько слов о том, как работать с авирой в отладчике. В последних версиях этого антивируса появилась защита собственных процессов. Чтобы она нам не мешала, возьмите папку авиры из Program Files и скопируйте в любое место – именно из него мы и будем работать. Также нам стоит переименовать avscan.exe в любое другое имя – его мы будем загружать в отладчик. Собственная защита авиры не даст загрузить в отладчик ни один файл с таким именем. Поэтому просто переименовываем. Напоминаю, что мы работаем со скопированной папкой авиры, а не с оригинальной! В оригинальной вам ничего не позволят сделать!

Теперь о запуске сканирования. Чтобы просканировать файл, нужно создать конфигурационный файл, внутри которого будет прописан путь к нашему файлу. А потом нужно передать путь к конфигурационному файлу в командную строку avscan.exe (в статье я буду применять это имя, но помните – мы этот файл переименовали!). Конфигурационный файл имеет такое содержание:

Код:
#########################################################
# $AV$SCANNER$AVP
#########################################################
# This file has been created automatically.
# DO NOT MODIFY!!
#########################################################
[CFG]
GuiMode=1
ExitMode=1

[SEARCH]
Parameterx00300432
Path0=C:\sample.exe

[CONTROLCENTER]
ProfileName=ShlExt

[SCANNER]

Порядок отладки такой: создаем текстовый файл cfg.txt с таким содержанием, только вместо c:\sample.exe прописываем путь к своему сканируемому файлу. Потом в отладчике открываем avscan.exe, а в качестве параметра прописываем путь к cfg.txt. Вот как это выглядит у меня:

37726147.png


С запуском разобрались, можно приступать к отладке. Кстати, забыл предупредить – после каждого сканирования файл конфигурации удаляется, его придется создавать заново. Итак, сначала возвращаемся к IDA Pro. Помните тот длинный список вызовов функций проверки? Перейдем в начало этого списка и запомним его адрес:

58825212.png


В моем случае этот адрес равен 100CDADB. Нам нужно определить самую первую функцию из списка проверок, которая вернет 0. Поэтому нам нужно поставить точку останова в начале списка и протрассировать его, пока не получим 0.

Для этого открываем в OllyDbg файл aeheur.dll и в командной строке пишем bp 100CDADB (помните, у вас этот адрес может быть другим). Теперь, когда мы будем отлаживать avscan.exe, отладчик остановится на этом самом адресе. Все, можно закрывать в отладчике aeheur.dll и открываем avscan.exe (не забываем про параметры в командной строке). Файл загружен, смело жмем F9. Авира подгружает свои длл читает файл, выполняет проверки и останавливается на том самом адресе, где мы поставили точку останова:

36985524.png


Мы находимся в самом начале списка проверок. Все, что нам теперь требуется – трассировать код клавишей F8 и смотреть на значение еах после вызова каждой из функций. Уверен, этот процесс можно автоматизировать, но я не реверсер и не умею этого. Итак, мы дошли уже трассировкой до самого ret, а 0 в еах так и не появился. Расстраиваться не стоит – функции проверок разбросаны в куче мест. Просто продолжаем трассировать, пока не получим 0 в еах. Трассировать приходится не долго, попадаем вот в это место:

41320592.png


Видите вызов функции, а за ним еах сразу равен 0? Эта та самая функция, которая нужна нам. Ставим на ее вызов точку останова. Не забываем в IDA Pro сразу же переходить на это же самое место, чтобы не заблудиться:

61698401.png


Вот так это место выглядит в IDA Pro. Сразу даем этой функции аналогичное название для удобства. Неопытный читатель заметит, что адреса в OllyDbg и IDA Pro отличаются – это все потому, что IDA грузит библиотеку по одному и тому же адресу, а OllyDbg всегда по разному. Чтобы не запутаться, сравнивайте адреса по последним 4 цифрам и все будет ясно.

Итак, мы нашли функцию, которая определяет файл, как вирус. Заходим в нее в IDA Pro и жмем F5. Мы видим кучу разных проверок. Как найти из них нужную? Правильно, опять нам поможет отладчик. Помните, мы поставили точку останова на этой функции? Перезапускаем avscan.exe в отладчике (напоминаю, что cfg.txt нужно будет создать заново! он уже удален авирой!) и жмем два раза F9 (два раза потому, что первый раз сработает точка останова в начале списка проверок – помните еще про нее? Впрочем, она нам не нужна и можно ее удалить – в этом случае жать F9 нужно будет один раз).

Точка останова сработала, мы стоим на вызове функции, которая дает детект. Заходим в нее (F7). Теперь трассируем по F8 все проверки, пока не будет вызвана функция расшифровки нужной нам строки. Как это определить? Я не буду это описывать. Немного опыта и Вы сами научитесь определять этот момент. Просто трассируйте до первого JMP (это совет навскидку, все-таки лучше потренируйтесь пару раз). Скажу честно, трассировать придется долго. Запаситесь терпением и хорошей реакцией.

Трассировал я долго, пока не вышел на этот момент (показываю в IDA Pro):

97908669.png


Знакомая картина? Помните тот список вызовов функций с проверками? Похоже, правда? Скажу по секрету, так оно и есть – это точно такой же список вызовов, но только других функций с другими проверками. Видимо, ни одна из проверок в текущей функции не дала результата и она полезла в подфункции с аналогичными проверками. Вобщем, пугаться не стоит, просто дальше трассируем по F8, пока не увидим в еах 0 после вызова. Как только увидели 0, ставим точку останова на этот вызов (все остальные точки останова удаляем), даем этой функции имя в IDA Pro:

93037445.png


87629764.png


Теперь в IDA Pro заходим в эту функцию, в OllyDbg снова перезапускаем avscan.exe, жмем F9 и после точки останова заходим в функцию (F7). Теперь мы внутри функции. Снова ищем нужную нам проверку – снова трассируем по F8, пока не найдем расшифровщик или JMP. Еще раз напоминаю – я делаю это для своего файла. На вашем файле, пусть даже детект с таким же именем, проверка может находиться совершенно в другом месте. Но алгоритм и логика поиска та же самая.

На этот раз долго трассировать не пришлось. Место заветного прыжка обнаружилось довольно быстро. Я покажу код сразу в IDA Pro (в OllyDbg не буду показывать):

75632533.png


В моем случае был выполнен прыжок:

Код:
102D2021                 ja      short loc_102D2093

Как вы видите из листинга, в том месте, куда идет прыжок, идет обращение к строке, которую мы искали с самого начала, а потом безусловный JMP, который мы искали только что трассировкой по F8.

Итак, место проверки найдено. Теперь в IDA Pro нажимаем F5. Перед нами отличный С-подобный код, который четко показывает все проверки, выполнение которых ведет к детекту. Половина пути пройдена, могу Вас с этим поздравить. Но остается не менее сложная и трудоемкая задача – определить, какие же конкретно флаги сравниваются и что за функции вызываются. Готовы? Поехали дальше.

3. Анализ проверяемых флагов

Поиск и анализ флагов – нема не менее трудоемкая, чем вся эта статья. Я не буду описывать всю логику реверсинга. Я лишь остановлюсь на основных принципах, которые вам следует использовать для анализа.
Авира в своем анализе использует две структуры. Я назову их AVIRA_INFO и SCAN_INFO. В первой больше информации о файле и черт знает чем еще, во второй – самые разные части РЕ и флаги, которые она выставляет в зависимости от разных значений РЕ.

Зайдите в таблицу экспорта файла aeheur.dll. Видите функцию module_get_api? Зайдите в нее. Она возвращает адрес массива ссылок. Перейдите по первой ссылке в этом массиве. Вы попадете в функцию. Откройте ее в хексрейсе, так наглядней. Видите вызов сначала колбека, а потом memset(v23, 0, 0x3720u) ? Это выделение памяти и ее обнуление для структуры AVIRA_INFO. Дальше ряд функций инициализируют некоторые значения этой структуры. Например,

Код:
memcpy((char *)v24 + 64, v29, 0x40u)

Эта функция копирует первые 64 байта с точки входа в отдельный буфер структуры AVIRA_INFO. Особо париться из-за этой структуры не стоит, в ней мало чего интересного.

Значительно ниже вы увидите вызов sub_10005E2B(v23). Зайдите в нее. Видите сначала вызов колбека, а потом:

Код:
 memset((void *)result, 0, 0x2478u)

Это уже создание структуры SCAN_INFO. Она является куда более интересной – все основные флаги находятся в ней. Чуть ниже идет вызов sub_1001604E – это самая важная функция. Она устанавливает если не все, то абсолютное большинство флагов в SCAN_INFO. Она довольно легкая для анализа. Просто очень длинная. Во всех проверках авира только сверяет разные флаги. Но их инициализация происходит именно в этой функции.

Возвращаемся к нашей функции проверки. Перед Вами С-подобный код, верно? Видите, очень много проверок полей переменной v1 и почти нет a1? Так вот, v1 – это указатель на SCAN_INFO, а1 – на AVIRA_INFO. Если присвоить этим переменным соответствующие типы (Y), анализ станет на порядки проще и удобнее. Это справедливо для всех функций проверки.

Имея все это, как продолжить анализ? Элементарно! Или смотрите в OllyDbg значения конкретных флагов и сравниваете их с полями РЕ (тут вам пригодится PE Tools), или в IDA Pro анализируете ту функцию, которая устанавливает флаги (можно иногда подглядывать в OllyDbg). На самом деле, это не сложно. За пару вечеров можно смело разобрать свой детект.

Еще пару слов о функциях в авире. Видите, она кроме флагов сравнивает и результаты некоторых функций? Причем, эти функции получают в качестве параметра указатели на шифрованные строки. Так вот, берем скрипт (помните, мы скрипт писали?) и расшифровываем эти строки. После этого становится четко видно, какие параметры принимают функции. Если в параметрах идет имя 1 длл и 1 функции, значит функция проверяет наличие этой функции в импортах (ну и каламбур). Если в параметрах только имя длл – значит проверяется наличие длл. Если в параметрах только длл, а результат функции сравнивается с каким-либо числом, то эта функция возвращает количество функций в импорте из данной длл. Т.е. у авиры не нужно рассматривать каждый байт – большинство кода интуитивно понятно.

Хочется дополнительно остановиться на некоторых косяках авиры. Судя по всему, в штаты к себе они набирают или пьяных китайских студентов, или пьяных индийских студентов. Вобщем, Вы часто можете встретить несколько функций одинакового назначения. Я находил около 5 копий одной и той же функции по расшифровке строки!!! Несколько копий проверки функции в импорте. Для проверки энтропии я видел около 7-10 абсолютно одинаковых функций!!! Это ахтунг, товарищи. То же самое касается и флагов – таблица директорий, разные части РЕ – все это дублируется по несколько раз в SCAN_INFO. Зачем? Одному Аллаху известно. Поэтому, если увидите функцию, которая делает примерно то же, что и предыдущая – не впадайте в панику. Это не косяк Вашего реверсинга, это скорее всего одна и так же функция. Ну или ее копия.

Также Вы можете встретить код в стиле:
Код:
dwTrue = 0;
if ()
{
    dwTrue = 1;
}
else
{
    dwTrue = 1;
    ...
}
Кстати, небольшое предупреждение – в авире также есть функции, которые проверяют наличие сразу нескольких длл в импорте. Количество параметров у них не фиксированное. Но HexRays покажет Вам только один параметр! Старайтесь сверять количество параметров HexRays и обычного листинга.

Заключение

После краткого и беглого анализа С-подобный код для моей проверки стал выглядеть так:

47567411.png


Как видите, ничего сложного. Можно углубиться еще сильнее, а можно остановиться и на этом.

Успехов! (с) Михрютка
 
Статья супер. Все просто без выпендрежа. Я с михрюткой часто общаюсь, меньшего от него не ожидал, как никак в этом ав он мастер. Конечно нужно учесть, что авиру реверсить легче всего, поэтому беремся за бита... :crazy: :D
 
Михрютка, не смотрел как связывается гуи с этой dll'кой?
как всегда - колбеки. Но я научился обходиться без гуя и ехе вообще, поэтому забросил их еще в самом начале - с тех пор только длл смотрю. В ехе там несколько своих внутренних структур - ну нафиг это все реверсить :)
Но, судя по экспорту aeheur.dll, гуй вызывает get_module_api, а потом все на колбеках. Но я этого не исследовал.
 
Спасибо, отличная статья!
Можете поподробней расписать заключение?
...С-подобный код для моей проверки стал выглядеть так:... навроде тут мы видим что авира проверяет то, потом то, и т.д.
Просто сухая фотка ни о чем не говорит.
 
через ida sync? :)
ты щас на каком этапе? я пока реверсю xlmrd.cvd, смотрю распаковку xmlrd.ivd. Потом думаю переходить к orice.rvd, но я совсем запутался в колбеках, а отладку в ида про применять не получается
 
C:\Program Files\Common Files\Softwin\BitDefender Scan Server\bdc.exe

В Plugins базы и все интересумое, пока что в общем пытаюсь понять принцип работы.

Расшифровка баз тривиальная тоже XORом.

bdcore.dll подгружает, из Plugins код, расшифровывает, который в свою очередь подгружает свои подмодули.
 
Расшифровка баз тривиальная тоже XORом.
нет :) там от плагина зависит
xlmrd.cvd да, простой ксор следующим байтом
а остальные плагины - зависит от одного из поля в заголовке их файла. Может быть как тот же ксор, так и замещение по таблице.
 
да. и с тем же именем и с измененым не получается... он запускается , ждет потом вылетает

AppName: avscan_.exe AppVer: 13.6.0.402 ModName: unknown
ModVer: 0.0.0.0 Offset: 0262118e

AppName: avscan.exe AppVer: 13.6.0.402 ModName: unknown
ModVer: 0.0.0.0 Offset: 0262118e


"AntiVir Desktop X\avscan_.exe" /CFG="C:\\c.txt"
"AntiVir Desktop X\avscan.exe" /CFG="C:\\c.txt"

Добавлено в [time]1359279618[/time]
если запускать с дефолтноу установочной папки. то все ок
 
да. вобщем отключил я защиту... щас щапускается с дефолтовой папки. вобщем запускаю я в ollydbg 1.10

C:\Program Files\Avira\AntiVir Desktop\avscan.exe /CFG="C:\\c.txt"


ща запускается... потом ждет ждет. и вот

access violation

21509328.jpg


Добавлено в [time]1359294060[/time]
защиту отключал. удалил эти файлы

avgnt c:\program files\avira\antivir desktop\avgnt.exe

avipbb c:\windows\system32\drivers\avipbb.sys
avkmgr c:\windows\system32\drivers\avkmgr.sys
ssmdrv c:\windows\system32\drivers\ssmdrv.sys
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх