Сейчас на форуме: (+6 невидимых)

 [email protected] —› Программирование —› code vs data.
. 1 . 2 . 3 . >>
Посл.ответ Сообщение


Ранг: 338.5 (мудрец), 349thx
Активность: 2.112.42
Статус: Участник

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

Здрасти.

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

-----
vx




Ранг: 590.6 (!), 408thx
Активность: 0.360.18
Статус: Модератор

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

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

-----
старый пень





Ранг: 338.5 (мудрец), 349thx
Активность: 2.112.42
Статус: Участник

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

r_e

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

-----
vx




Ранг: 2.5 (гость), 1thx
Активность: 0=0
Статус: Участник

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

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



Ранг: 488.1 (мудрец), 272thx
Активность: 0.350
Статус: Участник

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

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

-----
Наша работа во тьме, Мы делаем, что умеем. Мы отдаем, что имеем, Наша работа во тьме....





Ранг: 338.5 (мудрец), 349thx
Активность: 2.112.42
Статус: Участник

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

VodoleY

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

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

black7

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

-----
vx




Ранг: 2.5 (гость), 1thx
Активность: 0=0
Статус: Участник

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

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

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




Ранг: 338.5 (мудрец), 349thx
Активность: 2.112.42
Статус: Участник

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

black7

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

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

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

--> Link <-- vx

-----
vx




Ранг: 2.5 (гость), 1thx
Активность: 0=0
Статус: Участник

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

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

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


Ранг: 338.5 (мудрец), 349thx
Активность: 2.112.42
Статус: Участник

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

black7

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

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

black7

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

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

-----
vx




Ранг: 158.4 (ветеран), 123thx
Активность: 0.140.49
Статус: Участник

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

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




Ранг: 338.5 (мудрец), 349thx
Активность: 2.112.42
Статус: Участник

Создано: 25 декабря 2016 02:22
· Личное сообщение · #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. Но подобный анализ требует соответствующих ресурсов - дизасм должен возвращать эту инфу.

-----
vx





Ранг: 337.6 (мудрец), 224thx
Активность: 0.210.1
Статус: Участник
born to be evil

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

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

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

-----
От многой мудрости много скорби, и умножающий знание умножает печаль





Ранг: 338.5 (мудрец), 349thx
Активность: 2.112.42
Статус: Участник

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

ajax

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

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

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

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

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

-----
vx





Ранг: 241.9 (наставник), 107thx
Активность: 0.140.01
Статус: Участник

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

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




Ранг: 331.1 (мудрец), 561thx
Активность: 0.190.06
Статус: Участник

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

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

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

-----
Everything is relative...





Ранг: 338.5 (мудрец), 349thx
Активность: 2.112.42
Статус: Участник

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

Vamit

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

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

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

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

-----
vx




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

Создано: 06 января 2019 22:32
· Личное сообщение · #18

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



Ранг: 369.8 (мудрец), 400thx
Активность: 0.390
Статус: Участник

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

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

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

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

-----
PGP key <0x1B6A24550F33E44A>


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


Ранг: 271.4 (наставник), 331thx
Активность: 0.321.49
Статус: Участник

Создано: 06 января 2019 23:31
· Личное сообщение · #20

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

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

-----
2 оттенка серого




Ранг: 369.8 (мудрец), 400thx
Активность: 0.390
Статус: Участник

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

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

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

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

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

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

-----
PGP key <0x1B6A24550F33E44A>





Ранг: 271.4 (наставник), 331thx
Активность: 0.321.49
Статус: Участник

Создано: 06 января 2019 23:55
· Личное сообщение · #22

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

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

-----
2 оттенка серого




Ранг: 369.8 (мудрец), 400thx
Активность: 0.390
Статус: Участник

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

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

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

-----
PGP key <0x1B6A24550F33E44A>





Ранг: 568.2 (!), 465thx
Активность: 0.550.57
Статус: Участник
оптимист

Создано: 07 января 2019 02:43
· Личное сообщение · #24

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

-----
Чтобы правильно задать вопрос, нужно знать большую часть ответа. Р.Шекли.





Ранг: 1131.7 (!!!!), 447thx
Активность: 0.670.2
Статус: Участник

Создано: 07 января 2019 03:53
· Личное сообщение · #25

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

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


Ранг: 338.5 (мудрец), 349thx
Активность: 2.112.42
Статус: Участник

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

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

-----
vx





Ранг: 331.1 (мудрец), 561thx
Активность: 0.190.06
Статус: Участник

Создано: 07 января 2019 10:40
· Личное сообщение · #27

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

-----
Everything is relative...





Ранг: 338.5 (мудрец), 349thx
Активность: 2.112.42
Статус: Участник

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

Vamit

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

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

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

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

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

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

-----
vx




Ранг: 369.8 (мудрец), 400thx
Активность: 0.390
Статус: Участник

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

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

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

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

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

-----
PGP key <0x1B6A24550F33E44A>





Ранг: 338.5 (мудрец), 349thx
Активность: 2.112.42
Статус: Участник

Создано: 07 января 2019 11:19
· Личное сообщение · #30

ntldr

Бессмысленно это. Можно рассмотреть вариант - вызов сервиса, определение адресуемой области, разблокировка её и так рекурсивно. В системе есть несколько мониторов, через которое такое можно сделать.
Но учитывая множество нюансов, думаю не выйдет. Хотя при этом могут всплыть косяки в реализации нтапи.

-----
vx



. 1 . 2 . 3 . >>
 [email protected] —› Программирование —› code vs data.
Эта тема закрыта. Ответы больше не принимаются.
   Для печати Для печати