Здрасте. Такой вопрос. Допустим имеется код начиная с адреса Ip. Это будет первая ветвь. Данные начиная не с начала инструкции(напр. инструкция имеет размер 3 байта, адрес данных (Ip + 1)) образуют новый код. Это вторая ветвь. Адреса инструкций обеих ветвей не должны совпадать, иначе вторая ветвь совпадёт с первой(прервётся). Обе ветви должны выполнять определённую работу, тоесть это не просто мусор. Вопрос в том как такой код создавать. Написать такого типа простейшую процедуру, например копирование строки является весьма сложной задачей.
wsd Например код: Код (Text): $ 8B43 08 mov eax,dword ptr ds:[ebx + 8] $+3 033450 add esi,dword ptr ds:[eax + edx*2] Это первая ветвь. Вторая начинается со смещения Ip + 1: Код (Text): $+1 43 inc ebx $+2 0803 or byte ptr ds:[ebx],al $+4 34 50 xor al,50
Clerk Вы правы. Но такое думается создавать можно, используя взаимообратные инструкции. add\sub, inc\dec, or\and, и тп, при создании ветвей - держаться тактики "главной ветви". То есть строится первая ветка, и по ходу построения анализируются мнемокоды и подставляются команды для второй ветви). просто одна из ветвей будет разбавлена больше другая меньше. В целом реально. Но сам генератор будет сложен. На ваш вопрос нет полного ответа. Есть только некие идеи по планированию генератора.
Clerk т.е. хочеш сделать две дорожки 1: $ до END 2: $+1 до END и чтобы это был не мусор, а что-то осмысленное? ну одну осмысленную, а вторую мусорную надо и то сильно постараться( чтоб мусор был действительно безопасным для первой) а две не мусорных это запредельно. многое зависит от сочетания самих опкодов проца данных ему производителем. тут тебе нужен хороший компьютерный математик чтобы по научному доказать возможность или не возможность.
TermoSINteZ так вот как раз и нужен математик. может сложность генерации нужного кода будет сложнее факторизации RSA8kbit
TermoSINteZ Мусора минимум нужен. Опишите идеи ваши. t00x Данные можно ввести, как часть инструкции. Но это много мусора. С чего хотябы начать коденг ?
Перебрать все возможные комбинации. Но их ещё надо проанализировать. Очень сомневаюсь, что будет найдено что-то более-менее сложное. Сложность будет расти практически экспоненциально, полезность же будет сильно падать.
Clerk это не системщина и хак, и не ядро. это сложная математика. начать надо с математического доказательства осуществимости, а далее ресурсоёмкости процесса.
wsd Методом перебора можно найти самые длинные последовательности, начинать анализ именно с них, но скорее всего длина будет небольшая и ничего путного не выйдет.
wsd По-моему это даже не математика, так как проблема очень сложна. Только тупой перебор и голова. Предсказать что-либо практически нереально.
wsd Можно собрать такой код с минимальным количеством мусора. Причём тут доказательства. Мне не понятно как это делать и с чего начинать.
Clerk в природе бывают не осуществимые вещи или осуществимые с привлечением не реальных ресурсов. чтобы не заниматься невыполнимыми вещами, сначала математически доказывается возможность осуществимости задачи. с математической модели я тоже не очень силён в матане
Clerk кстати у меня где-то был ликбез варезный по математической оценке разных характеристик алгоритмов. если что могу в пм.
wsd Ну например как предложил t00x - использовать данные одной инструкции в качестве другой. Это например mov r32,imm32. Но такой код не оптимален, это переизбыток мусора. Проблема в этом решении что нельзя оптимизировать.
Clerk ну одну идею я уже озвучил. Когда вы создаете код 1 ветви и при этом генерируете вторую, на основе первой. Ну и наверно нужна машина состояний (состояний процессора для каждой ветви). Если бред то извините. Но похоже, что можно начать с этого: 1) Создаем команду первой ветви, если меньше 3х байт (только для первого прохода), то добавляем еще, иначе переходим в пункт 2 2) Сохраняем машину состояния для первой ветви 3) На основе последних 3х байт строим команду второй ветви (из таблицы, например, берем вначале то, что подойдет под X\..\3\2\1 байт с конца. Если не подошло - удаляем пред команду. переходим в пункт 1 (восстанавливаем состояние первой ветви, берем и разбавляем команду (разделяем, переделываем ее не трогая логику первой ветви). Если подошло то в пункт 4. 4) Создаем логику второй ветви так, чтобы не менялась машина состояний первой ветви (если меняется - компенсируем). Переходим в пункт 5. 5) Сохраняем машину состояния второй ветви. Если не закончили, то в пункт 1. То есть - будет две машины состояния, будет 2 или больше таблиц коллизий, и таблицы опкодов, которые перебираются. Например push заменить на mov \ sub для стека. или там mul заменить на lea, и так далее. Вот как то так. Кстати скорее всего код будет хорошо разбавлен переходами, колами, ретами и тп. Наверно PS. в ARM было бы проще такое сделать )