eXeLab
eXeL@B ВИДЕОКУРС !

ВИДЕОКУРС
выпущен 4 ноября!


УЗНАТЬ БОЛЬШЕ >>
Домой | Статьи | RAR-cтатьи | FAQ | Форум | Скачать | Видеокурс
Новичку | Ссылки | Программирование | Интервью | Архив | Связь

Русский / Russian English / Английский

Сейчас на форуме: AlexNVZ (+4 невидимых)
 · Начало · Статистика · Регистрация · Поиск · ПРАВИЛА ФОРУМА · Язык · RSS · SVN ·

 eXeL@B —› Программирование —› code vs data.
. 1 . 2 . 3 . >>
Посл.ответ Сообщение


Ранг: 321.3 (мудрец)
Статус: Участник

Создано: 23 декабря 2016 10:22 · Поправил: difexacaw New!
Цитата · Личное сообщение · #1

Здрасти.

Задача отличить код от данных. Тоесть имеем указатель на массив, нужно аналитически узнать что это код. Хотелось бы посмотреть что уже сделано. Когда то давно была попытка реализовать, толи deroco, толи есчо кто, не могу найти. Анализер иды не годится, он слишком толст и не профайл, а самое главное не умеет разбирать наверно дампы вне пе.

Ранг: 575.6 (!)
Статус: Модератор

Создано: 23 декабря 2016 10:26 New!
Цитата · Личное сообщение · #2

Банально частотный анализ, если массив достаточно большой.
Можно дизасмом пробежаться на предмет валидности.
Матчинг типовых блоков, типа push ebp;mov ebp, esp...


Ранг: 321.3 (мудрец)
Статус: Участник

Создано: 23 декабря 2016 10:30 New!
Цитата · Личное сообщение · #3

r_e

Вариантов слишком много, вот хотелось бы посмотреть уже собранные в одном месте

Ранг: 2.5 (гость)
Статус: Участник

Создано: 23 декабря 2016 22:33 New!
Цитата · Личное сообщение · #4

Если точка входа = начало массива, то дизасмом пройтись с анализом jcc адресов.

Ранг: 488.4 (мудрец)
Статус: Участник

Создано: 23 декабря 2016 23:26 · Поправил: VodoleY New!
Цитата · Личное сообщение · #5

black7 отлично.. call eax
есть такой подход.. я себе делал.. wallker назвал. гуляет по коду.. ток разрезелвить относительные ссылки при этом нельзя..
ТС как бы тут не надоел.. но ставит немногу другую задачу.. анализ сырых данных. в статике увы не все сделать можно.. есть 3 варианта анализа.. статический.. статико динамический.. и выполнение кода в песочнице.. как пример.. но все они не дают 100 проц результата


Ранг: 321.3 (мудрец)
Статус: Участник

Создано: 24 декабря 2016 00:45 New!
Цитата · Личное сообщение · #6

VodoleY

> все они не дают 100 проц результата

Почему же, можно выделить критерии, которые однозначно определят что данные это данные, например повторение ветвлений с одинаковым условием или адресация 8/32 с одним и тем же регистром(eg add [eax],al) etc. Не говоря уже про запрещённые/невалид инструкции, префикс лока и др. Если код в пе, то наличие релоков существенно упрощает задачу.

black7

Это самая базовая проверка - не пересечение инструкций.

Ранг: 2.5 (гость)
Статус: Участник

Создано: 24 декабря 2016 02:16 New!
Цитата · Личное сообщение · #7

VodoleY пишет:
отлично.. call eax

Я же не говорю про полное покрытие. call eax вообще лесом, EIP +2 и далее. Если трасса получается более менее, то можно посчитать еще энтропию и сделать выводы.
Вообще от задачи зависит. Если на входе вообще непонятно что, и не известно, что это может быть, то тут нужна мощная эвристика с сочетанием кучи методов...


Ранг: 321.3 (мудрец)
Статус: Участник

Создано: 24 декабря 2016 02:19 New!
Цитата · Личное сообщение · #8

black7

В том и задача. В принципе фундаментальный шаблон я запилил(анализер), но это ничего не решает. Опять же хотелось бы глянуть что реализовано.

Добавлено спустя 3 часа 2 минуты
Собрал тестовый семпл, фактически шаблон(ядро анализера).

При тестах на 8-ке при покрытии 80к инструкций фейлов нет. Для начала сделал с релоками. Сюда нужно будет прикрутить табличные проверки на инвалид инструкции и пр. Очень быстрый анализер.

--> Link <-- vx

Ранг: 2.5 (гость)
Статус: Участник

Создано: 24 декабря 2016 16:32 New!
Цитата · Личное сообщение · #9

difexacaw Ого, Indy, я тебя даже не узнал! Ты научился разговаривать как человек!
Думаю, еще лет 5 и ты научишься не создавать тем с вопросами, только чтобы выложить свои исходники на масме.

| Сообщение посчитали полезным: xdf



Ранг: 321.3 (мудрец)
Статус: Участник

Создано: 25 декабря 2016 01:12 New!
Цитата · Личное сообщение · #10

black7

Что это значит ?

Вопрос открыт, а что выложено - это шаблон и способ тестирования. Эта не простая тема и нужно на что то опираться, как то тестить.

black7

> Если на входе вообще непонятно что

Исходная задача приводящая к данной - в динамике отделяется код от данных, при передаче управления, это событие детектится. Приложение взято под своего рода трассировку/супервизор. Событие передачи управления на не определённый адрес(код/данные?) имеет огромный тайминг. После этого события оно никогда не наступит, так как адрес помечен содержащий код и иначе обрабатывается - при обнаружении ссылки на него она изменяется. Но это нельзя сделать при инициализации, когда ссылка куда то загружается и используется далее из вне. Для этого необходимо определить что по ссылке код.

Ранг: 143.2 (ветеран)
Статус: Участник

Создано: 25 декабря 2016 02:08 New!
Цитата · Личное сообщение · #11

difexacaw
Обычно в программах управление на данные не передается. Имеется передача управления? Там код.


Ранг: 321.3 (мудрец)
Статус: Участник

Создано: 25 декабря 2016 02:22 New!
Цитата · Личное сообщение · #12

rmn

Есть массив векторов, в частности фиксапов(релоков). Их нужно разделить на данные/код. Это нужно сделать до начала выполнения.

Добавлено спустя 1 час 36 минут
Пока я выделил базовые критерии, позволяющие определить что код не является кодом. Видимо необходимо два таких типа использовать, вероятность: +- код. Так в общем случае однозначно определить код можно только не приемлемым путём - выполнив высокоуровневый анализ, декомпиляция и символьное исполнение(выделить алгос, трек графа данных etc) и прочие не пригодные вещи.

Проще выделить элементарные критерии, по которым однозначно можно определить что это не код. Пока я выделил следующие группы:

A. Релоки. Релок может быть только на Disp32 или Imm32.

B. ModRM:

Невалид адресация в случае отсутствия комплексной базы в ModRM. Это условия:

1. !Base или Base = Index. Тогда если нет смещения, то адресация невалид. Иначе выборка из урезанного сегмента(Fs на NT с лимитом 4K).

2. Адресация ниже стека:

[esp + SIB -N] -> валид только если есть индекс и scale = 1.

C. Операнд является частью базового регистра: add [eax],al это nothing конструкции.

Необходимо использовать причинно следственные зависимости, так например флажки и регистры, к примеру после обнуления флага не может следовать его проверка, eg: xor r,r/jz. Но подобный анализ требует соответствующих ресурсов - дизасм должен возвращать эту инфу.


Ранг: 334.1 (мудрец)
Статус: Участник
born to be evil

Создано: 25 декабря 2016 22:20 · Поправил: ajax New!
Цитата · Личное сообщение · #13

да, по релокам сканить на валидность инструкции -1-2-3... от оффсета. если пара-тройка таких фиксапов - явно код. если нет релоков - все сложнее

ps: masm32 убивает. это звездец.


Ранг: 321.3 (мудрец)
Статус: Участник

Создано: 26 декабря 2016 02:35 · Поправил: difexacaw New!
Цитата · Личное сообщение · #14

ajax

Для релоков возможны два варианта:

1. Фиксап на Disp32 в MRM.
2. Фиксап на Imm32. Imm32 всегда расположен за Disp32. Тоесть возможны макс два фиксапа для одной инструкции.

Любой иной случай(фиксап пересекает иструкцию) - невалид.

> ps: masm32 убивает. это звездец.

Что именно, названия регистров ?


Ранг: 240.4 (наставник)
Статус: Участник

Создано: 26 декабря 2016 10:49 New!
Цитата · Личное сообщение · #15

xor r,r/jz такого мусора полно в коде после обфускаторов.


Ранг: 325.8 (мудрец)
Статус: Участник

Создано: 26 декабря 2016 11:47 New!
Цитата · Личное сообщение · #16

difexacaw пишет:
Анализер иды не годится, он слишком толст и не профайл, а самое главное не умеет разбирать наверно дампы вне пе.

А вы пробовали? Все он умеет разбирать, если правильно настроить.
Всё что вы тут пишите это только вероятностная оценка код-данные, 100% результат это никогда не даст. Его можно получить только в реалии, учитывая не только сам код, но и среду его создания и исполнения.
Даже Ида не дает 100% результат, как простой пример - таблицы виртуальных функций. А при наличии обфускаторов и вм разделение код-данные стирается практически полностью и разобраться в этой каше сможет только декомпилятор, учитывающий особенности конкретной вм.
Поэтому определитесь сначала с конкретной задачей - что, для чего и зачем. Только в этом случае можно создать что-то стоящее в анализе, иначе повторение велосипеда без достижения приемлемого результата.


Ранг: 321.3 (мудрец)
Статус: Участник

Создано: 26 декабря 2016 12:22 · Поправил: difexacaw New!
Цитата · Личное сообщение · #17

Vamit

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

Только один сложный случай есть, это когда данные перемешаны с кодом, так например включение данных и загрузка ссылки на них через call/db. В иных любых случаях положение инструкций в блоке значения не имеет, они выделяются в графе, данные расположенные между блоками кода не мешают.

> Всё что вы тут пишите это только вероятностная оценка код-данные, 100% результат это никогда не даст.

Почему же вероятностная. К примеру обнаружение пересечения инструкций однозначно говорит что это не код. И прочие многие критерии, например описанные в #12. Такие конструкции не могут быть использованы.

Ранг: 2.8 (гость)
Статус: Участник

Создано: 6 января 2019 22:32 New!
Цитата · Личное сообщение · #18

difexacaw по итогу то, какое решение? Какие стратегии решения хороши, какие плохи, чем?

Ранг: 370.2 (мудрец)
Статус: Участник

Создано: 6 января 2019 23:20 · Поправил: ntldr New!
Цитата · Личное сообщение · #19

В статике в общем случае - задача не решаема. Код может быть одновременно и данными для другого кода А после отделения кода от данных у вас возникнет задача отделить данные от данных (определить границы массивов, структур, переменных). Это ещё большая жопа.

Единственное более-менее полноценное решение - информация от компилятора. Компилируем с ключом /Gy, компилятор кладёт каждую функцию и каждый элемент данных (массив, переменную, структуру, итд) в отдельную секцию COFF объектного файла. COFF'ы элементарно дизассемблируются и превращаются в полный граф программы, описывающий все взаимосвязи кода и данных. С таким описанием легко творить всё что вздумается.

Работая с чужим кодом - исходим от того что у нас на входе и какая задача решается. Разобрать в статике возможно не всё, да и обычно не нужно. В динамике - любой извратный код можно корректно дизассемблировать и рекомпилировать. Там логика простая: что исполняется в данный момент / исполнялось раньше - то и есть код. Остальное - данные.

| Сообщение посчитали полезным: difexacaw



Ранг: 226.3 (наставник)
Статус: Участник

Создано: 6 января 2019 23:31 New!
Цитата · Личное сообщение · #20

ntldr пишет:
В статике в общем случае - задача не решаема.

Решаема, если эта задача не умозрительная. Причем технически довольно несложно, можно даже скриптом для иды оформить, заменив слабоватые встроенные средства анализа. Если от точки входа до безусловного перехода/ретёрна нету несуществующих/привилегированных инструкций, обращений по запрещенным адресам памяти и прочей дичи, данные можно считать кодом. Если не ставить целью сотворить неебесное чудо, которое переварит что угодно, в том числе как угодно обфусцированное и на любую архитектуру.

Ранг: 370.2 (мудрец)
Статус: Участник

Создано: 6 января 2019 23:38 · Поправил: ntldr New!
Цитата · Личное сообщение · #21

f13nd пишет:
Если не ставить целью сотворить неебесное чудо, которое переварит что угодно, в том числе как угодно обфусцированное и на любую архитектуру.

Такое чудо как раз не сильно сложно сотворить. Просто переваривать будет по кусочкам и налету. До изобретения аппаратной виртуализации, виртуальные машины именно так работали.

Добавлено спустя 11 минут
f13nd пишет:
Если от точки входа до безусловного перехода/ретёрна нету несуществующих/привилегированных инструкций, обращений по запрещенным адресам памяти и прочей дичи, данные можно считать кодом.

А теперь представь что твой блок кода закончился на что-то вроде jmp [jump_table + esi*4]. Вот и начались первые сложности, откуда дизасмить дальше и как узнать размер таблицы. Таблицы могут связывать мелкие фрагменты кода (GCC любит таблицы переходов). Попробуй собери из этой каши всю функцию нигде не накосячив. Предположим что даже релоков нет и таблицы переходов (которые являются данными) идут с фрагментами кода вперемешку.

IDA такое сама до конца не раскручивает, приходится вручную расставлять код/данные. Совсем другое дело когда разбираем COFFы со всеми символами...


Ранг: 226.3 (наставник)
Статус: Участник

Создано: 6 января 2019 23:55 New!
Цитата · Личное сообщение · #22

ntldr пишет:
А теперь представь что твой блок кода закончился на что-то вроде jmp [jump_table + esi*4].

Я не жадный, мне достаточно десятка валидных инструкций. Вероятность того, что какие-то данные случайно сложатся во что-то правдоподобно напоминающее код, невелика.

Ранг: 370.2 (мудрец)
Статус: Участник

Создано: 7 января 2019 00:03 · Поправил: ntldr New!
Цитата · Личное сообщение · #23

X64 код (применительно к отделению его от данных) ещё не радует своей дефолтовой базонезависимостью. В x86 на mov, eax, [variable] будет стоять релок внутри опкода, в x64 релоки остались только там где данные ссылаются на что-то. Меньше инфорации для анализа.

В x86 так удобно было ходить наоборот, от данных к ссылающемуся на них коду, через релоки.


Ранг: 539.1 (!)
Статус: Участник
оптимист

Создано: 7 января 2019 02:43 New!
Цитата · Личное сообщение · #24

difexacawОпять вы схватились за кактус голыми руками, если файл стандартный то решение найти просто, а если это полиморф встроенный в фотку голой саши грей то только ручки и голова, либо разработайте нейросеть обучающийся)))


Ранг: 1120.2 (!!!!)
Статус: Участник

Создано: 7 января 2019 03:53 New!
Цитата · Личное сообщение · #25

ClockMan, ты же понимаешь, что говоришь с Инде из 2016-го?

| Сообщение посчитали полезным: ClockMan



Ранг: 321.3 (мудрец)
Статус: Участник

Создано: 7 января 2019 07:22 New!
Цитата · Личное сообщение · #26

Никак это не решается на бинарных файлах. Если бы это было возможно, то можно было бы сделать хорошую защиту, удалив из памяти весь исполняемый образ.


Ранг: 325.8 (мудрец)
Статус: Участник

Создано: 7 января 2019 10:40 New!
Цитата · Личное сообщение · #27

Не всё так грустно, как вы малюете, если правильно поставить задачу и задать пограничные условия, то она полностью решается статическим эмулятором (полная эмуляция инструкций, регистров, стека, памяти) для любого типа бинарного кода (чистый, обфусцированный, виртуализованный).
Простая статика (дизасм с набором доп. условий) заткнется на любых косвенных переходах, а динамика пропустит очень много полезного кода.
Это не голословное высказывание, а проверенное решение на коде разных типов.


Ранг: 321.3 (мудрец)
Статус: Участник

Создано: 7 января 2019 11:03 · Поправил: difexacaw New!
Цитата · Личное сообщение · #28

Vamit

Вы понимаете что помешались на вирт машинах ?

А какой толк в данной задаче от части, выделит выборка конкретную область данных. Это никак не поможет узнать лимиты области. Полнейшая чушь.

Не знаю зачем эту тему подняли, но задача не решаема.

Я возвращался к этому несколько раз, затем забыл вовсе, решение не возможно. Из последних идей - я думал как использовать ядерную валидацию указателей. Прежде обращения к памяти из км происходит проверка памяти, либо это происходит при самом обращении к ней, в любом случае сервис возвращает статус памяти(#AV: N/A). Но затем я к данной теме больше не возвращался, это врядле возможно реализовать.

Вся суть в двух проблемах - определить указатель и определить его размер(те адресуемой области).
Для процессорных инструкций это просто, все области линейны. Системные сервисы работают иначе, они используют структуры, в которых так же есть указатели на другие структуры. Может и можно определить их размер, последовательным перезапуском сервисов, но что то мне подсказывает что в конце ничего не выйдет хорошего, учитывая сервисы гуя и прочее.

Не могу сказать конкретно, я это подробно больше не рассматривал. Могу лишь описать основную идею защиты. Анклав(область памяти, состояние которой зависит от ридера) не может быть реализован для обычной секции кода(не известно что передавать в ядро, параметры памяти для каждого сервиса). Именно по выше описанной причине. Иначе возможно убрать из памяти весь образ, зная сервисные параметры формировать их в буферах. Но опять же такое врядле возможно без хардкода.

Ранг: 370.2 (мудрец)
Статус: Участник

Создано: 7 января 2019 11:04 · Поправил: ntldr New!
Цитата · Личное сообщение · #29

Vamit пишет:
она полностью решается статическим эмулятором (полная эмуляция инструкций, регистров, стека, памяти) для любого типа бинарного кода (чистый, обфусцированный, виртуализованный)

Эмуляция - это уже как-бы не совсем статика. И у эмуляции всегда есть ограничения, невозможно полноценно эмулировать внешнюю среду (это всё что находится дальше процессора и памяти. включает в себя софт, хард и даже пользователя...).

difexacaw пишет:
Вся суть в двух проблемах - определить указатель и определить его размер(те адресуемой области).

Касательно системных структур, хорошая практика отыскивать указатель в секции данных и код который на него ссылается. В структурах переимещаемся по известным оффсетам (захардкожены, либо берутся из PDB символов), либо определяем оффсеты через объект с частично известным содержимым.


Ранг: 321.3 (мудрец)
Статус: Участник

Создано: 7 января 2019 11:19 New!
Цитата · Личное сообщение · #30

ntldr

Бессмысленно это. Можно рассмотреть вариант - вызов сервиса, определение адресуемой области, разблокировка её и так рекурсивно. В системе есть несколько мониторов, через которое такое можно сделать.
Но учитывая множество нюансов, думаю не выйдет. Хотя при этом могут всплыть косяки в реализации нтапи.
. 1 . 2 . 3 . >>
 eXeL@B —› Программирование —› code vs data.
Эта тема закрыта. Ответы больше не принимаются.

Оригинальный DVD-ROM: eXeL@B DVD !

Вы находитесь на форуме сайта EXELAB.RU
Проект ReactOS