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

Статья Умный мусор: построение логики

Ar3s

Старожил форума
Легенда
Регистрация
30.12.2004
Сообщения
3 357
Реакции
1 404
358f8ac7b5aa.jpg
Введение

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

Кто противник

Допустим, что происходит проверка файла, заражённого нашим вирусом. Антивирус может действовать так:

--------------------------------------------------------------------------------------------------------------
- запустит поверхностный анализ файла: его структуры и каких-то участков кода (сбор информации для начала работы эмулятора, кодо-анализатора, эвристика, может чего-то ещё);
--------------------------------------------------------------------------------------------------------------
- далее, запускается эмуль, в процессе работы которого могут быть вызваны: анализатор кода (сбор данных для (дальнейшей работы) эмулятора и эвристика), а также сигнатурный анализ (поиск известных сигнатур в уже проэмулированном коде);
--------------------------------------------------------------------------------------------------------------
- после отработки эмуля в дело вступает эвристический анализ собранных данных (сигнатур для нашего виря ещё не сделали=)), где происходит подсчёт баллов "опасности". Если полученный результат больше заданного предела - получите клеймо heur-virus'a.
--------------------------------------------------------------------------------------------------------------

От эмуля нам поможет рабочая антиэмуль, от сигнатур - генератор мусора, который (как оказывается xD) использует наш вирь. Но если созданный трэш-код окажется слабым, то нас накроет эвристика.


План наступления

Итак, для построения более качественного трэш-кода, вначале я предлагаю выбрать, под генерируемый код какого компилятора мы будем "косить": ms, borland etc. После того, как выбран компилер (например, ms), можно ещё определить, под какой режим генерации/оптимизации мы будем подстраиваться ("min size"/"max speed"). Это всё, конечно же, не обязательно, но желательно. Так как под разными режимами код генерируется по-другому. Например, для ms-компилера, команда занесения единицы в регистр в режиме "max speed" (в основном) будет такая:

Код:
mov	eax, 1	;0xB8 0x01 0x00 0x00 0x00

А для "min size"

Код:
xor	eax, eax;0x33 0xC0
inc	eax	;0x40

Трэшген может генерировать оба эти варианта, но более правдоподобно смотрится, если держаться одной тактики (неизвестно, какие извращения будут в новых версиях эвристиков).

Далее, помимо разных фичезов, которые вы встроите в трэшген, он также должен уметь генерировать "реалистичный" код (похожий на обычный код стандартных программ, написанных на ЯВУ), а именно:

--------------------------------------------------------------------------------------------------------------
+ "правильные" инструкции (опкоды и операнды - например, команда "mov eax, ecx" может быть закодирована с помощью двух разных опкодов: 0x8B 0xC1 и 0x89 0xC8 -> ms-компилер юзает первый вариант; некоторые команды с использованием регистра EAX, имеющие "оптимизированные" варианты опкодов; etc);
--------------------------------------------------------------------------------------------------------------
+ "правильные" конструкции (например, test/cmp без последующей инструкции jmp/jxx - очевидное палево);
--------------------------------------------------------------------------------------------------------------
+ множество различных команд (использующих регистры, адреса памяти и т.п.), функции (с прологами/резервированием стэка/эпилогами etc и команды с использованием локальных переменных, входящих параметров), winapi и другие;
--------------------------------------------------------------------------------------------------------------
+ "правильная" статистика частоты встречаемости опкодов (собираем стату в обычных прогах и используем её; для более точного результата можно собирать стату только в файлах, собранных выбранным ранее компилером);
--------------------------------------------------------------------------------------------------------------
+ нормальная энтропия (в битах ~ [5.5; 6.8]; кстати, энтропия будет примерно в заданном диапазоне, если генерить "правильный" код + использовать стату встречи опкодов (сюда можно добавить и логику команд));
--------------------------------------------------------------------------------------------------------------
+ только живой код (который может выполниться);
--------------------------------------------------------------------------------------------------------------
+ etc;
--------------------------------------------------------------------------------------------------------------

Но даже такой трэш-код, построенный с учётом данных пунктов, может легко ловиться эвристикой.

Полезный мусор

Основная засада в том, что мусорный код - это только мусор, набор бесполезных инструкций. В этом и кроются причины гнева эвристиков. А раз так, значит трэш должен стать полезным. Для этого надо реализовать ещё 2 задачи:

-------------------------------------------------------------------------------------------------------------
1. полезный код должен использовать результат работы трэш-кода (или наоборот, трэш-код должен как-либо повлиять на работу полезного кода) aka "псевдо-цель";
-------------------------------------------------------------------------------------------------------------
2. "LOGICAL TRASH" technique;
-------------------------------------------------------------------------------------------------------------

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

Код:
mov	eax, 100
mov	ecx, eax
sub	ecx, 95

После его выполнения ECX = 5. И данное значение можно добавить к ключу для расшифровки вирусного кода (применений куча).
Однако, сгенерированный трэш-код может быть и таким:

Код:
mov	eax, 100;1
mov	ecx, eax;2
mov	ecx, eax;3
mov	ecx, eax;4
sub	ecx, 95	;5

После его выполения ECX также равно 5. Но команды 2 и 3 выдают себя с потрохами, за что будут наказаны эвристикой. Решение состоит в построении "логичного" мусора.

"LOGICAL TRASH" technique

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

Примерно такую логику я реализовал в новой версии своего движка xTG (v2.0.0), который работает по следующей схеме:

ef98453d250e.png



Распишем подробно:

----------------------------------------------------------------------------------------------------------
I.вначале, конечно же, вызываем модуль генерации команд;
----------------------------------------------------------------------------------------------------------
II. генерируем "правильную" команду: правильные опкоды и остальные байты. Да, кстати, если разработанный двигатель логики (ДЛ) будет применяться к сторонним трэшгенам (или другим движкам), то ДЛ также должен проверять, правильно ли построена команда (aka проверка на уровне байтов);
----------------------------------------------------------------------------------------------------------
III.вызываем модуль логики, передавая в него адрес только что созданной команды;
----------------------------------------------------------------------------------------------------------
IV. за дело принимается парсер команд. Парсер может быть функцей, являющейся частью модуля логики, а может быть и отдельным самодостаточным движком (дизасм). Первый случай хорошо подходит, если модуль логики является частью генератора мусора. Тогда в функции парсера будут разобраны только те команды, которые может генерировать двигл. Второй случай хорошо подходит, если модуль логики является самостоятельным движком. И при этом мы не знаем, какие команды могут генерироваться.

Парсер выясняет, какая перед ним команда, и получает её параметры (операнды: регистры, адреса etc) - в соответствии с этим сохраняет в некоторую структуру данные параметры и выставляет определённые флаги. Заполненная структура будет использоваться анализатором команд (об этом ниже). Также, например, если встретилась команда mov ecx, dword ptr [403008h] и т.п., тогда парсер заменит адрес 403008h на другой, соответствующий ему адрес в выделенной памяти для корректной эмуляции команды;
----------------------------------------------------------------------------------------------------------
V.затем эмулируем (скорректированную) команду. Эмуль, по аналогии с парсером, может быть как встроенной функцией в модуле логики, так и полноценным движком-пирожком;

Эмуль получает адрес команды, подготавливает специальную среду, копирует туда команду и эмулирует. Причём эмуляция может быть как минимум 3-х видов: прямой запуск в специальной среде, полная имитация выполнения команды и сочетание этих двух методов (для большинства команд хватает 1-ого метода). Результат эмуляции (текущие значения параметров команды и др.) сохраняем в переменных: виртуальных регистрах и др.

Кстати, эмуль - козырная технология для вирей, с помощью которой можно творить очень интересные темы (для UEP'a, виртуальных машин, "logical trash" tech, морфинга и прочих вкусностей);
----------------------------------------------------------------------------------------------------------
VI. и после вызываем анализатор команд/корректор логики. Анализатор, по аналогии с парсером и эмулем, может быть как встроенной функцией в модуле логике, так и полноценным двиглом;

Анализатор, на основе данных от парсера (заполненная структура) и эмуля, решает, подходит ли команда по логике или нет.

Анализ команды проходит в 2 этапа:

1. Проверка параметров команды.

Сначала анализатор должен понять, какие есть параметры, и как их проверять. Для этого он использует флаги, переданные парсером. Набор флагов может быть такой:

--------------------------------------------------------------------------------------------------------
Код:
LGC_INSTR_INIT	equ	00000000000000000000000000000001b;команда инициализации параметров; 
LGC_INSTR_CHG	equ	00000000000000000000000000000010b;команда изменения параметров; 
LGC_P1_DST	equ	00000000000000000000000000000100b;первый парам - приёмник
LGC_P1_SRC	equ	00000000000000000000000000001000b;первый парам - источник
LGC_P2_DST	equ	00000000000000000000000000010000b;второй парам - приёмник
LGC_P2_SRC	equ	00000000000000000000000000100000b;второй парам - источник
LGC_P1_REG	equ	00000000000000000000000001000000b;первый парам - регистр
LGC_P1_ADDR	equ	00000000000000000000000010000000b;первый парам - адрес
LGC_P1_NUM	equ	00000000000000000000000100000000b;первый парам - число
LGC_P2_REG	equ	00000000000000000000001000000000b;второй парам - регистр
LGC_P2_ADDR	equ	00000000000000000000010000000000b;второй парам - адрес
LGC_P2_NUM	equ	00000000000000000000100000000000b;второй парам - число
--------------------------------------------------------------------------------------------------------

Этими флагами можно описать почти все инструкции (некоторые флаги можно убрать). Если инструкция содержит больше 2 параметров, тогда остальные хранятся в отдельном поле.

Далее, по флагам определяется, что и как чекать: проверки на возможность инициализации параметров, на изменение их значений, на использование их в других командах и многое другое. Результат каждой проверки заносится в маски. Их 2: regs_init & regs_used. Грубо говоря, это 2 dword'a, где каждый бит соответствует определённому параметру (например, какому-то регистру). Причём, биты в regs_init показывают, можно ли инициализировать параметр или нет (защита от повторной инициализации). А по битам в regs_used узнаём, можно ли вообще использовать параметр в командах или нет.

2. Проверка состояний параметров команды

Итак, если первый этап пройден, то это означает, что параметры годные. Продолжим.

Состояние - это некоторое сохранённое значение, которое принимал параметр. Состояния всех параметров хранятся в таблице состояний, которая представляет собой буфер определённого размера.

Значит, анализатор берёт текущее значение параметра, которое мы получили с помощью эмуляции (и сохранили, например, в виртуальном регистре), и сверяет его со всеми накопленными состояниями данного параметра.
Если совпадение найдено, тогда команду считаем мусорной, проверка не пройдена. В этом случае из таблицы состояний берём последнее сохранённое состояние данного параметра и делаем его текущим (сохраняем это состояние в виртуальном регистре); а также восстановим маски на предыдущие значения. Если совпадение не найдено - значит это новое состояние параметра, команда прошла проверку. Добавляем это значение в таблицу состояний;
----------------------------------------------------------------------------------------------------------
VII.переходим снова в модуль генерации команд. Смотрим, какое значение вернул нам модуль логики: если 0, тогда команда не подходит по логике - по её же адресу сгенерируем новую команду (перезапишем).
Прыгаем на пункт II. если 1, тогда команда подходит по логике. Прыгаем на пункт VIII.
----------------------------------------------------------------------------------------------------------
VIII. увеличиваем адрес (для генерации новой команды) на размер проверенной команды. И выясним: если мы сгенерировали нужное количество байтов, тогда прыгаем на пункт IX. Если не все, тогда на пункт II.
----------------------------------------------------------------------------------------------------------
IX. выходим;
----------------------------------------------------------------------------------------------------------

Примеры генерации простого мусора

19c374ac2dc9.png


------------------------------------------------------------------------------------------------------------------------
В примере 1.1 первые 2 команды нормальные, а третья - мусорная. Регистр EDI инициализировать можно, но он примет такое же значение, какое имеет сейчас - ненужная инициализация. Пример 2.1 (и все остальные в дальнейшем) показывает правильный вариант инициализации.
------------------------------------------------------------------------------------------------------------------------
В примере 1.2 первые 3 команды правильные, а 4-ая - мусорная. Регистры EAX & ECX снова примут значения, которые уже имели (проверка состояний параметров).
------------------------------------------------------------------------------------------------------------------------
В примере 1.3 первые 2 команды правильные, а 3-я - мусорная. EDI += 0 (проверка состояний);
------------------------------------------------------------------------------------------------------------------------
в примере 1.4 первые 3 команды правильные, а 4-я - мусорная. Регистр EDX нельзя инициализировать, если он прежде не повлиял на значение другого параметра (проверка параметров);
------------------------------------------------------------------------------------------------------------------------
в примере 1.5 первые 4 команды правильные, а 5-ая - мусорная. После выполнения первых 4-x команд состояния регистра EAX будут такие: 1000, 999. А после выполнения 5-ой команды EAX = 1000. Такое состояние уже было (проверка состояний параметров).
------------------------------------------------------------------------------------------------------------------------

Позитив =)

Реализацию техники "логичного мусора", наглядные примеры генерации трэш-кода, а также более полное понимание задумки - всё это ты найдешь в сорцах xTG v2.0.0.

Следует сказать, что в xTG наиболее лучшее качество логики получается при генерации линейного трэш-кода без winapi-функций.
В остальных случаях логика будет нечёткой, но будет: на ветвлениях и с винапишками. Это связано с модулем логики - чем он мощнее, тем качественней выхлоп.

Если же не устраивает логика каких-либо инструкций, достаточно просто установить другие флаги.

Также, возможен вариант применения логики для уже сгенерированного кода. Однако искомый код может быть на 100% отличный от исходного.

Используя данную технику, наш мусор становится полезным и логичным, что позволяет довольно эффективно обходить эвристику. И только комплексное применение техник воплотят наши желания в реальность. Ура!

Используемая инфа

1. beauty on the fire "Эмуляция программного кода", 2004, http://uinc.ru/articles/47/
2. beauty on the fire "Анализаторы кода в антивирусах", 2004, http://uinc.ru/articles/45/
3. Sl0n "Полиморфизм. Новые техники", 2004, http://vx.netlux.org/lib/vsl05.html

[ + ]
август, 2011

m1x
pr0mix@mail.ru
EOF

вирмэйкинг для себя...искусство вечно

Автор pr0mix
p.s. by Ar3s статья опубликована с просьбы автора. Это первая публикация у нас на форуме. Прошу отнестить с пониманием и поддержать материал обсуждениями. Спасибо.
 
как насчет использование математических функция для генерации мусора?
вообще или конкретно в данном движке?

Если первое - да, конечно. Можно использовать функи для генерации определённого мусора ("правильного", антиэнтропийного и др.), непоследовательной его записи - что сразу придумалось.
Если второе - используется простая арифметика на уровне 1-3 класса. Этого достаточно =)
 
Итак, для построения более качественного трэш-кода, вначале я предлагаю выбрать, под генерируемый код какого компилятора мы будем "косить": ms, borland etc. После того, как выбран компилер (например, ms), можно ещё определить, под какой режим генерации/оптимизации мы будем подстраиваться ("min size"/"max speed"). Это всё, конечно же, не обязательно, но желательно. Так как под разными режимами код генерируется по-другому. Например, для ms-компилера, команда занесения единицы в регистр в режиме "max speed" (в основном) будет такая:

Почему не хотите генерировать мусор на уровне С-шных исходников малвары и уже замусоренный файл скармливать компилятору?
 
Почему не хотите генерировать мусор на уровне С-шных исходников малвары и уже замусоренный файл скармливать компилятору?
предпочитаю больше морфинг/генерацию кода - имхо нужный контроль и гибкость.
А вообще, комбинация тоже рулит: морф/ген сорцов + последующий морф/ген кода
 
pr0mix, спасибо за статью, позвонвательно. В целом сейчас очень мало людей которые продвигают тему, и не жадничают делиться ею с другими.

p.s. Информация должна быть доступна всем, а кто как её будет использовать это уже личное дело каждого.
 
demien
А что продвигать. Нужно для начала запилить декомпилятор, который бинарь псевдокодом опишет, затем этот код будет изменён и скомпилен. А регистры менять и прочие логические манипуляции это тривиально и не эффективно. Разбухает бинарь во много раз в каждом покалении.
 
Ar3s Очччень приятно что дамага цветет и пахнет:) искренне рад за портал, Ar3s, и всем ребятам кто его поддерживает огромное человеческое спасибо! ;) приятно видеть новые обзоры и статьи. Ar3s так держать, Вы молодец!!!) уважаю людей кто если начал, то делает, и надо признаться делает это хорошо.

Indy Человек очччень ярко отразил идею и конкретные примеры в ввиде алгоритма того что СЕЙЧАС АКТУАЛЬНО, а это многого стоит, мед на ложечке никто и не обещал, идея изъяснена отлично как я понял, ну а реализовывает каждый сам, на сколько знания позволят.
Разбухает бинарь во много раз в каждом покалении
а кто говорит о том чтобы каждый раз конечный резалт обрабатывать, морф оригинала + обработка мусором. ну и все же мусор есть мусор;) я думаю если грамотно им пользоваться + как показано в статье использовать мусор с полезной нагрузкой, будет мего чудно;) В любом случае Вы можете предложить свой вариант...
p.s. Indy Вы случайно не с васма?;)

pr0mix,
А вообще, комбинация тоже рулит: морф/ген сорцов + последующий морф/ген кода
Комбинация отличная, спору нет, примеров с реализацией на асме не встречали? а то все что встречал, на уровне кода уже...

p.s.s. ИМХО приятно что люди, как pr0mix стали посещять дамагу, это говорит о том, что дамага примного выросла и готова к таким людям.
 
demien
морф оригинала
Своё тело не морфим по вашему, а таскаем в виде поксоренного блока(генерация тела тоже самое, так как оно генерится темже телом, пермутация тут не рассматривается так как требует компилятора) - этож полиморфизм.

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

Комбинация отличная, спору нет, примеров с реализацией на асме не встречали?
по отдельности данные морфы можно найти на хэвенсе. А комбинацию, в общем случае, сделать несложно, в отличие от того же компиля. Если к тому же он будет обладать само-компиляцией и другими фичами.

Я к тому что если человеку достаточно мусорного движка, более менее актуального в наши дни, то он и не будет прыгать к процессу реализации декомпилятора с анализатором блоков кода по графам, а будет курить в сторону своего генератора мусора.
это ты наверное про скамерцию? =)
потому как с тобой не согласен. Такие мега-проекты и другие (интеграция в код etc), будут реализовывать, хотя бы по одной простой причине - это интересно Ж)
Ещё: кто юзает, тот знает -> полиморф + трэшген остаётся актуальным действом при наличии антиэмуля.
 
совсем необязательно, всё дело в реализации. Простейшее решение - метаморфизм, когда первое поколение (ака скелет) - тягаем с собой, и перед каждой мутацией издеваемся над ним. Также можно написать и оптимизатор для пермутанта, но это другая история =)
полностью солидарен, это и имел ввиду в 11ом посту.

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

это ты наверное про скамерцию? =)
потому как с тобой не согласен. Такие мега-проекты и другие (интеграция в код etc), будут реализовывать, хотя бы по одной простой причине - это интересно Ж)
Ну тут у медали две стороны: быстрый кэш, в принципе можно и компетентным трешгеном с интелектуальным подходом обойтись, вторая сторона это любопытство, challenge (более подходящего слова не подобрал), испытание для кодера-вэиксера, и не сколько деньги а интерес в себя может побудить на написания нечто необычного и ранее не реализуемого, в конкретно Вашем случае смею предположить как раз вторая сторона медали... ;)

Ещё: кто юзает, тот знает -> полиморф + трэшген остаётся актуальным действом при наличии антиэмуля.
Это дооо ;) есть и иные комбинации...
 
Sl0n пишет:
В чём же заключается пермутация? Базовым алгоритмом пермутирующих движков является дизассемблирование кода с последующей его мутацией и ассемблированием.
Аху[Пии..]ть, для меня мир перевернулся, больше и сказать нечего..
явно аффтАр аццкий пожиратель грибов %)))

pr0mix пишет:
Трэшген может генерировать оба эти варианта
Он обязан генерировать оба варианта, но рандомно
Что-то типа:
Код:
If(RTrue())
{
  mov eax, 1; 0xB8 0x01 0x00 0x00 0x00
}
else
{
  xor eax, eax; 0x33 0xC0
  inc eax; 0x40
}
pr0mix пишет:
(неизвестно, какие извращения будут в новых версиях эвристиков)
И никаких там извращений не будет (им, чем проще - тем лучше) – ИМХО

pr0mix пишет:
+ нормальная энтропия (в битах ~ [5.5; 6.8]; кстати, энтропия будет примерно в заданном диапазоне, если генерить "правильный" код + использовать стату встречи опкодов (сюда можно добавить и логику команд));
[5.5; 6.8] – это уже критична и не желательна (обязательно один из 43 какой-нибудь «Ахтунг» заорет)
нормальная энтропия [4.12; 4.68] или ниже, макс. 5.7, 6.25 – должен быть предел
да и не такая уж это тривиальная задача удержать нормальную энтропию при генерации пусть даже и правильного трэш-кода (насколько я помню)
если взять, к примеру, 256 байт
Код:
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 00
Получим
Размер 256
MD5 d4002182ecd7ee0a4428e74166d9ef78
энтропия 0.04
и к примеру, 256 байт
Код:
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
Получим
Размер 256
MD5 d68251a836de0f1b0336fc5585555374
энтропия 1.00
ну и
Код:
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F
80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F
A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF
C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF
E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF
Получим
Размер 256
MD5 e2c865db4162bed963bfaa9ef6ac18f0
энтропия 8.00
отсюда видно, что чем больше разных байт, тем выше энтропия, но чем больше количество (в процентном соотношении) тем ниже
сталобыть чем больше одинаковых команд в трэше, тем выше шанс удержать энтропию в нужном диапазоне [4.12; 5.7]
примитивный вариант снизить энтропию - дописать в конец секции нулей с обязательным выравниванием на...
короче, ИМХО
 
Indy
Согласен, возможно реализация метода требует неких усилий и возможно даже будет не столь эффективна, как ожидалось, но.. человек делится своими идеями, мыслями, наработками, а это много стОит. Сейчас хорошим вариантом является "умный" мусорный код, разбавляющий код малвари. Под умным я подразумеваю логичность мусора, подобно коду стандартной программы, что поможет в некоторых случиях опустить использование антиэмуляции, т.к. в ней отпадет нужда. И хоть я не использую двиг промикса в решении собственных задач, для меня мусорная кодогенерация и разбавление основного кода является отличным вариантом решения моих задач.

имхо это моё мнение
 


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