Если вы почитаете эту статью:Малварь как искусство - Десяток трюков как обойти эмулятор антивируса и скрыть свой код
То сложится впечатление, что для обхода детекта достаточно например выделить память гиг, или сделать задержку в минуту или час.
Но на самом деле, это нетак, вернее способы применимы, но при определённых условиях, давайте разбираться.
Ну во первых нормальные антивирусы вполне себе могут эмулировать и VirtualAllocExNuma (кстати в той статье были и ошибки в коде (поправил), также для работы нужно подключить и хидерники (гуглите сами, кому нужно)) и проверять выделение памяти, типо mallock.
Кстати про маллок, на самом деле он просто увеличивает размер виртуальной памяти, а free уменьшает размер виртуальной памяти по мере необходимости. :)
Например, рассмотрим приложение размером 64 K (включая размер bss) с начальным размером "кучи" равным 0. При этом используется от 0 до 64 К в виртуальной памяти (общий размер виртуальной памяти = 64 K + размер стека), как показано на Рисунке.
Рисунок Выделение памяти в "куче".
Теперь предположим, что приложение делает вызов malloc(4096). Это увеличит размер виртуальной памяти до 68 K, как показано на Рисунке. Фактическая физическая память выделяется только на фактическое время использования.
Когда-же это работает ?
В начале разберёмся что такое эмуляция кода ? По простому антивирус "исполняет" код и по шагам добирается до нашего "вредоносного кода", далее принимает решение о детекте используя сигнатуры и другие виды анализа (например количество определённых апи и т.д.).
Но понятно, что ресурсы антивируса ограничены, иначе-бы проверка одного файла занимала часы, а-то и проверка программы с например while (1), вообще могла повиснуть.
Поэтому антивирусы эмулируют не все апи, также "частично" могут эмулировать какие-то ресурсоёмкие задачи. Как уже написанно, "частично" эмулируются бесконечные циклы, выделение памяти и т.д.
Этим и пользуются хакеры.
Но повторюсь, тут нужно не просто выделять память, а как-бы пользоваться ей.
Вот простой пример:
В bad_code будет код, который хотим скрыть. В случае исполнения функции вернём ноль. Там также можно дополнительно что-то делать (вычисления и т.д.).
Ну-тут понятно, выделяем память, наполняем её значением 0x88. Далее освобождаем и вызываем функцию bad_code. Т.к. размер памяти слишком большой, большинство эмуляторов "частично" проэмулируют этот код и не доберутся до bad_code ! :)
Ещё вариант, в темпе создавать файл, размером 1 гигабайт, с рандомным содержимым (лучше бинарник), далее считывать его в специально сделанный буфер и проверять память на валид.
Т.е. алгоритм примерно такой:
1)Выделить буфер маллоком, ну-ладно сжалимся и выделим 250 метров; :)
2)Заполним буфер мемсетом, неважно чем, я обычно люблю 0x55; :)
3)Создадим файл в темпе, или в папке с программой и запишем туда наш буфер, получим файл 250 метров с говном, я-бы даже на рандоме значения сделал, да-так лучше будет;
4)Выделяем новый буфер маллоком в 250 метров, считываем туда наш файл.
5)Проверяем область памяти из пункта два и пункта четыре. Например при помощи memcmp:
if (memcmp (src, dst, SIZE_MEM_MALLOC) == 0)
{
//Выполняем свой код и чистим всё (Или наоборот как нужно, чистим всё и выполняем код)
}
6)Если проверка не равна, то переходим в цикле на пункт один. Ну и не забывайте очищать память и закрывать/удалять файл. Ибо незачем хранить 250 метров говна, так-же как и такой объём памяти постоянно резервировать тоже плохо.
Я понимаю вирусы и т.д., но пожалейте своих жертв.
Всё на таком алгоритме отсеиваются все популярные антивирусы.
Всем удаче и не пишите локеры. :)
То сложится впечатление, что для обхода детекта достаточно например выделить память гиг, или сделать задержку в минуту или час.
Но на самом деле, это нетак, вернее способы применимы, но при определённых условиях, давайте разбираться.
Ну во первых нормальные антивирусы вполне себе могут эмулировать и VirtualAllocExNuma (кстати в той статье были и ошибки в коде (поправил), также для работы нужно подключить и хидерники (гуглите сами, кому нужно)) и проверять выделение памяти, типо mallock.
Кстати про маллок, на самом деле он просто увеличивает размер виртуальной памяти, а free уменьшает размер виртуальной памяти по мере необходимости. :)
Например, рассмотрим приложение размером 64 K (включая размер bss) с начальным размером "кучи" равным 0. При этом используется от 0 до 64 К в виртуальной памяти (общий размер виртуальной памяти = 64 K + размер стека), как показано на Рисунке.
Рисунок Выделение памяти в "куче".
Теперь предположим, что приложение делает вызов malloc(4096). Это увеличит размер виртуальной памяти до 68 K, как показано на Рисунке. Фактическая физическая память выделяется только на фактическое время использования.
Когда-же это работает ?
В начале разберёмся что такое эмуляция кода ? По простому антивирус "исполняет" код и по шагам добирается до нашего "вредоносного кода", далее принимает решение о детекте используя сигнатуры и другие виды анализа (например количество определённых апи и т.д.).
Но понятно, что ресурсы антивируса ограничены, иначе-бы проверка одного файла занимала часы, а-то и проверка программы с например while (1), вообще могла повиснуть.
Поэтому антивирусы эмулируют не все апи, также "частично" могут эмулировать какие-то ресурсоёмкие задачи. Как уже написанно, "частично" эмулируются бесконечные циклы, выделение памяти и т.д.
Этим и пользуются хакеры.
Но повторюсь, тут нужно не просто выделять память, а как-бы пользоваться ей.
Вот простой пример:
Код:
#define SIZE_MEM_MALLOC 1024*1024*1024
uint32_t *memdmp = NULL;
while(memdmp != NULL)
{
memdmp = malloc(SIZE_MEM_MALLOC);
memset(memdmp, 0x88, SIZE_MEM_MALLOC);
free(memdmp);
err = bad_code(void);
if (!err) break;
}
В bad_code будет код, который хотим скрыть. В случае исполнения функции вернём ноль. Там также можно дополнительно что-то делать (вычисления и т.д.).
Ну-тут понятно, выделяем память, наполняем её значением 0x88. Далее освобождаем и вызываем функцию bad_code. Т.к. размер памяти слишком большой, большинство эмуляторов "частично" проэмулируют этот код и не доберутся до bad_code ! :)
Ещё вариант, в темпе создавать файл, размером 1 гигабайт, с рандомным содержимым (лучше бинарник), далее считывать его в специально сделанный буфер и проверять память на валид.
Т.е. алгоритм примерно такой:
1)Выделить буфер маллоком, ну-ладно сжалимся и выделим 250 метров; :)
2)Заполним буфер мемсетом, неважно чем, я обычно люблю 0x55; :)
3)Создадим файл в темпе, или в папке с программой и запишем туда наш буфер, получим файл 250 метров с говном, я-бы даже на рандоме значения сделал, да-так лучше будет;
4)Выделяем новый буфер маллоком в 250 метров, считываем туда наш файл.
5)Проверяем область памяти из пункта два и пункта четыре. Например при помощи memcmp:
if (memcmp (src, dst, SIZE_MEM_MALLOC) == 0)
{
//Выполняем свой код и чистим всё (Или наоборот как нужно, чистим всё и выполняем код)
}
6)Если проверка не равна, то переходим в цикле на пункт один. Ну и не забывайте очищать память и закрывать/удалять файл. Ибо незачем хранить 250 метров говна, так-же как и такой объём памяти постоянно резервировать тоже плохо.
Я понимаю вирусы и т.д., но пожалейте своих жертв.
Всё на таком алгоритме отсеиваются все популярные антивирусы.
Всем удаче и не пишите локеры. :)