Assembler
Алгоритмы
Ненормальное программирование
Программирование
Комментарии 24
+6
Очень давно (больше 20 лет назад) я написал интерактивный дизассемблер, подобный IDA — с возможностью тегирования любого байта кодового сегмента (код, данные [со спецификацией простых и сложных типов и указателей на них], неопределенный, подозрительный) и атрибутами (точка_входа, процедура, потеря_управления). Можно было запускать пробный анализ с любой точки, а также видеть набор инструкций с произвольным смещением относительно текущего блока любого типа — то есть, можно было посмотреть интерактивный листинг, скажем со смещения +1 прямо рядом с основным. Этот тул был сделан для однокристальных МК, которые, конечно, колятся несравнимо легче, чем современные «большие» процессоры, но имхо ручной анализ кода после подозрительных мест — а это прерывание дерева исполнения, скажем процедурой (выход из нее может подменять адрес возврата в стеке), индексного джампа или прямого колдовства со стеком — сможет распознать неадекватность хотя бы по обращению по бесмыссленным адресам или странной побочной логике выполнения набора инструкций со смещением. Здесь для инженера-реверсера главное — догадаться, что стеганография имеет место быть в этом бинарном куске, хотя бы по одному подозрительному месту. Дальше уже дело техники — можно и тул написать, который облегчит выуживание параллельных цепочек
+8
Наверное я не очень понимаю, но:

— Дизассемблеры и так постоянно 'пускаются по ложному следу', при дизассемблировании именно этот параметр на постоянном контроле, и навык опознавания такого момента у хакеров хорошо развит.

— Против трассировки такая обфускация (и наверное любая другая, любое однопоточное решение) никак не поможет, а значит сводит результат всех усилий к нулю.
+4
Эх, часто данную технику использовали не для запутывания, а во всяких Hugi Size Coding Competition. Вот там были неимоверные шедевры!
+2
натыкался в IDA на подобный код — обнаруживается по странных джампах на срединьі инструкций. Если отменить то, что дизасемблировала сама ІДА и указать ей началом инструкции место джампа, то получается совсем другой код. Даже проникся уважением к написавшему такой ювелирный код — но как защита оно никакое ;)
0
CMOVcc, пожалуйста уберите из списка и, если хотите, добавьте PREFETCHxxx (их довольно много разных).
+2
Описанной технологии уж лет 20 как, может и поболее.

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

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

Высший пилотаж был бы использовать одни и те же байтовые блоки для двух реально используемых цепочек инструкций, чтобы если IDA показывает инструкцию одной цепочки, то одна или две инструкции другой цепочки — портятся. Но насколько мне помнится, такая дичь не встречалась. Да и это был бы просто вопрос чуть большего неудобства — пришлось бы дополнительные финты к IDA пристраивать…
0
Лучше уж придумать свой байт-код и виртуальную машину его испольнения. Как было (есть?) у HASPа и многих других. Мороки по анализу и раскодированию таких защит гораздо, на мой взгляд, больше.
+1
Такие монструозные инструкции у меня всегда вызывают повышенный интерес, а уж NOP отличный от 0x90 абсолютно всегда.
0
Вот тоже хотел заметить, что 9-байтовый NOP — это довольно чёткое палево, особенно когда они все длинные (пусть и несколько рассеянные по коду). На самом деле я давно уже не ковырялся с дизасемблированием, но раньше мне никогда не попадалось никаких, кроме однобайтовых, отличющихся только длинной серии. Даже не подозревал о том, что другие существуют. Возможно современные компиляторы их используют активнее.
Интересен смысл их наличия. Это такой способ ускорить обработку, сведя 9 байт в одну команду вместо 9 (пусть и быстрых)?
+1
Такие монструозные NOPы служат в целях отладки, чтобы не править десяток байт, а всего 3-4 закинуть. В релизной версии софта — пффф, General Failure, u haz biin detekted
0
В современных процессорах анализатор склеивает что 9 обычных, что один длинный, согласно StackOverflow, поэтому разницы нет. Появляется разница при работе со специфичными кристаллами.
0
Тогда тем более непонятно, зачем их вообще придумали.
Специфичные х86 — это которые?
-1
А открыть официальную документацию, где инглишем по белому написано как именно выбирать NOPы (и да, там целых три пункта и подробное объяснение «почему так») — не судьба, нэ?

Или вот статейка — там даже целый раздел есть «оптимизация NOPов» с графиками и цифрами.

Всё-таки не стоит забывать о том, что Stack Overflow — это таки свалка, где кто угодно может писать что угодно…
+1
Например, студийный компилятор использует многобайтовые nop (я встречал пятибайтовые) для выравнивания кода.
+1
Не знаю как в студии, но в GCC он это делает всегда, когда вы компилируете под Pentium Pro или новее. То есть сегодня — почти всегда.

Просто потому что многобайтные nop'ы быстрее. Но он всегда использует нули в DISP.
+1
Анализ подобного кода это скорее базовое упражнение для человека изучающего возможности любого вменяемого дизасемблера, нежели серьезный прием по затруднению анализа кода. Даже дедушка hiew позволял задавать разные точки входа.
0
Hiew под линуксом запускается через wineconsole и работает, хоть и не растягивается на весь экран. :(
0
К подходу, как отметили выше, интерес сугубо академический: при всех усилиях на сокрытие стойкость к анализу низкая. Потому что на стороне взломщика играет энтропия :)
0
Этот же подход неплохо описан в этой бумаге: Obfuscation of Executable Code to Improve Resistance to Static Disassembly, раздел junk insertion.

Авторы отмечают одну интересную особенность: «само-лечащийся дизассемблер» (self-repairing disassembly). Дизассемблер может встретить несколько «мусорных» инструкций, но рано или поздно он вернется на верный трэк.
Кроме того, этот метод имеет разное влияние на разные дизассемблеры. В случае линейного алгоритма неверно распознаны в среднем 39% инструкций, а в случае рекурсивного алгоритма — 25%.

Ну и конечно непонятно как этот подход по мнению VolKarev помогает в случае динамического анализа.
Только полноправные пользователи могут оставлять комментарии. , пожалуйста.