Загрузка...

Полиморфный код на ассемблере с шифрованием (обход VirtualBox, AnyRun, дампа памяти, 5 блоков кода)

Тема в разделе Вирусология создана пользователем LLCPPC_inactive4415647 22 авг 2021. (поднята 23 авг 2021) 3092 просмотра

Загрузка...
  1. LLCPPC_inactive4415647
    LLCPPC_inactive4415647 Автор темы 22 авг 2021 Не мир пришел Я принести на землю, но меч 245 15 авг 2021
    Увидел вот эту тему - https://zelenka.guru/threads/1299659/ И вот эту - https://zelenka.guru/threads/389054/
    Ну куда это годится, господа?
    Решил вам показать мой старый полиморфный исходный код.
    Написан в далёком 2015.

    Что в итоге выполнения кода:
    * Отладчик будет дёргаться, и в некоторых местах трассировка будет выполнять совсем не те команды, что нужно
    * Защита от дампа. В коде, что я написал, затираются все выполненные участки, и в самый конец программы - вся память будет абсолютно пустой.
    * (Модифицировал перед написанием статьи) Защита от Any Run, VirtualBox (Тем самым, если был обнаружен один из них - код до конца не расшифруется. Если же добавить проверку всех остальных виртуальных систем - мы получим настоящий неуловимый вирус)

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

    Код написан на ассемблере, и упакован в 5 разных блоков с разным ключём. На 2015 хватало обычного XOR-шифрования, я задействовал макрос в FASM для этого, но в коде, что рассматривается ниже - его не будет. Это защита от любителей копировать код. Так же в коде удалена одна важная строка, это так же защита от копирайта - этот код всего-лишь для обучения, вы можете написать точно такой же, если захотите.

    Для понимания и чтения вам понадобятся уже знания по:
    * Ассемблер x86, и x86_64 тоже. Желательно уже дойти до расширений, продвинутого уровня.
    * FASM, его синтаксис. В коде используются анонимные метки - @@, и его аналоги адресов - @b - последняя метка сверху, @f - последняя метка снизу
    (А ещё директивы section, import, readable и много других!)

    [IMG]

    [IMG]

    [IMG]

    [IMG]


    Приступим.

    (Я люблю засовывать весь код в импорт-таблицу, чтобы окончательно убить декомпилятор)

    Первый фрагмент:


    Код
    section    'LLCPPC'    import readable writeable executable
    dd 0, 0, 0, RVA kernel, RVA kernel_table
    kernel_table:
    GetProcAddress dq RVA _GetProcAddress
    LoadLibrary dq RVA _LoadLibraryA
    dq 0


    _GetProcAddress: dw 0
    db 'GetProcAddress', 0

    _LoadLibraryA: dw 0
    db 'LoadLibraryA', 0

    kernel: db 'kernel32.dll', 0

    align 8
    FUNCTION_TABLE:
    dq 6 dup(0)

    align 32
    FUNCTION_TABLE_NAMES:
    @@:
    db 'CreateToolhelp32Snapshot'
    times 32-($-@b) db 0
    @@:
    db 'Process32First'
    times 32-($-@b) db 0

    @@:
    db 'Process32Next'
    times 32-($-@b) db 0

    @@:
    db 'CloseHandle'
    times 32-($-@b) db 0

    @@:
    db 'ExitProcess'
    times 32-($-@b) db 0

    @@:
    db 'Sleep'
    times 32-($-@b) db 0

    @@:
    db 'GetTickCount'
    times 32-($-@b) db 0

    FUNCTION_TABLE_NAMES_END:

    encrypt FUNCTION_TABLE_NAMES, ($-FUNCTION_TABLE_NAMES), FUNCTION_TABLE_NAMES_KEY

    Здесь я прописываю руками импорт-таблицу PE структуры, и запрашиваю только две функции - GetProcAddress и LoadLibraryA.
    Остальные функции зашифрованы скрытым макросом.


    FUNCTION_TABLE_NAMES это таблица имён, для неё так же выделено ровно столько адресов (8 байт) на FUNCTION_TABLE.
    Я использую директиву times, чтобы добиться для каждой строки с названием функции - 32 байта, это нужно для оптимизированного цикла в точке входа, где берутся строки.

    А теперь давайте глянем на точку входа!



    Код
    start:
    lea eax, qword[Initialization]
    @@:
    jmp @f
    db 0x99, 0xFE, 0xEF
    @@:
    xor byte[eax], INITIALIZATION_KEY

    lea eax, qword[rax+1]

    cmp eax, Init_END
    jne @b

    Initialization:
    ....
    Итак, функция Initialization это наш первый зашифрованный блок кода! И здесь вы уже видите вторую технику "побесим декомпилятор" - неизвестные инструкции. Я прыгаю на метку после неизвестных инструкций, чтобы не обрабатывать их, но они всё равно есть, и дизассемблера\декомпилятора это ой как бесит

    Блок мы расшифровываем в цикле XOR инструкцией, и ключом, который определён в самом начале. Полный код будет ниже, и вы сможете всё рассмотреть.
    Далее сравниваем, не равен ли адрес на Initialization - адресу Init_END (конец функции), и если нет - продолжить расшифровку (прыгнув на анонимную метку (@@) вверх с помощью @b)

    А теперь сама функция Initialization:

    Код
    nitialization:
    lea eax, qword[FUNCTION_TABLE_NAMES]
    @@:

    xor byte[rax], FUNCTION_TABLE_NAMES_KEY
    jmp .undefined_command
    db 0x7F, 0x9F, 0xEF
    .undefined_command:
    lea eax, qword[rax+1]

    cmp eax, FUNCTION_TABLE_NAMES_END
    jne @b
    .......
    В EAX помещаем адрес FUNCTION_TABLE_NAMES(массив названий функций, разделённый на 32 байт блоками), и расшифровываем их. Помните? Мы же их расшифровали ещё на этапе компиляции кода. Здесь алгоритм точно такой же - XOR байт по адресу в EAX, и проверка, не конец ли функции это.

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

    Код
    lea    rcx, qword[kernel]
    call qword[LoadLibrary]
    mov r13, rax
    lea r14, qword[FUNCTION_TABLE]
    lea r15, qword[FUNCTION_TABLE_NAMES]
    @@:
    mov rdx, r15
    mov rcx, r13
    call qword[GetProcAddress]

    mov qword[r14], rax

    lea r14, qword[r14+8]
    lea r15, qword[r15+32]

    cmp r15, FUNCTION_TABLE_NAMES_END
    jne @b
    ...
    Готово! После выполнения - все наши нужные фунцкии в таблице FUNCTION_TABLE.
    Но стоп! Мы же расшифровали и таблицу имён, и наш код с расшифровками, это же просто сдампить... А нет! Не так всё просто. Мы же пишем на ассемблере, давайте-ка просто всё это к херам затрём:


    Код

    cld
    xor rax, rax
    lea rdi, qword[FUNCTION_TABLE_NAMES+8]
    mov rcx, (FUNCTION_TABLE_NAMES_END-FUNCTION_TABLE_NAMES)/8
    rep stosq
    Я специально сделал блоки ровно по 32 байта, чтобы они делились на 8. Тем самым, мы выигрываем в оптимизации, и можем быстренько по 8 байт блоками зачистить все 32*8 - имён функций. Прекрасно, не так ли?
    Ну вот и всё, мы зачистили память, теперь от имён функций, до расшифровки и инициализации - и следа не осталось!

    А что теперь? Да всё, что захотим!
    Ну давайте, к примеру, ещё добавим проверку на Any Run, и VirtualBox, а после чего - выведим сообщение о том, что полиморфный код успешно отработан.

    Наша "вспомогательная функция" для проверки тоже зашифрована! И это уже ВТОРОЙ блок!
    Давайте же его расшифруем:


    Код

    lea rax, qword[HelpCode_Start]
    @@:

    xor byte[rax], HELP_CODE_KEY
    jmp .undef_instr
    db 0x9F, 0xFF, 0x0F, 0xEE
    .undef_instr:

    lea rax, qword[rax+1]
    cmp rax, HelpCode_END
    jne @b

    jmp HelpCode_Start+1
    ...
    Техника одинаковая, и не забываем провести носом перед декомпилятором неизвестными инструкциями))

    Отлично, код расшифрован из функции инициализации, и передано управление второму блоку. Так давайте же отпразднуем, и затрём все следы к херам!
    Код

    HelpCode_Start:
    xor rax, rax
    lea rdi, qword[start]
    jmp @f
    db 0x99, 0xF0, 0xF5, 0xD0
    @@:
    mov rcx, (Init_END-start)/8
    jmp @f
    db 0xDD, 0xFE, 0xFF, 0x09
    @@:
    rep stosq
    ...

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


    Код

    FUNCTION_TABLE_NAMES FUNCTION_TABLE
    [1] FunctionName = FunctionAddr
    32 bytes...
    [2] FunctionName = FunctionAddr
    Т.к у нас размер адреса 8 байт, тогда мы можем взять первый\второй\третий\... адрес с помощью абсолютно лёгкой формулы -
    FunctionAddr = Counter*Size
    (Где Counter - нужный нам номер функции, Size - размер одного элемента (размер должен быть равен для всех элементов))

    Итак, вроде всё разъяснил.
    Следующий фрагмент, после зачистки - обнаружение пошаговой отладки:


    Код

    call qword[FUNCTION_TABLE+6*8]
    mov r15, rax

    mov rcx, 2000
    call qword[FUNCTION_TABLE+5*8]

    call qword[FUNCTION_TABLE+6*8]
    sub rax, r15
    ...
    6-я функция в таблице - GetTickCount
    5-я функция в таблцие - Sleep

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

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

    Собственно, алгоритм:

    r15 = GetTickCount()
    Sleep(2000)
    rax = GetTickCount()

    Далее отнимаем rax-r15, и получаем задержку.
    Сравниваем, не больше ли задержка, чем 2500.
    Если больше, тогда скармливаем ревёрсеру фейк-код:


    Код

    cmp rax, 2500
    jmp @f
    db 0x09, 0x90, 0xEE
    @@:
    jg fake_code

    И не забываем бесить декомпилятор и дизассемблер. Не дадим ему проломиться сквозь наше творение.

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


    [CODE]
    fake_code:
    xor rcx, rcx
    xor rbx, rbx
    xor rdx, rdx
    xor rax, rax
    @@:
    add rcx, rbx
    sub rcx, rdx
    mul rbx
    shl rax, 4
    add rax, rdx
    mov rax, rbx
    add rbx, 90
    cmp rbx, 0xF0
    cmove rax, rbx
    add rax, rcx
    sub rax, rdx
    ; ... write more!

    cmp rax, 0xDD
    jne @b

    ret
    [/CODE]
    Итак, возвращаемся, если же это не пошаговая отладка, тогда давайте посмотрим, не AnyRun ли это, или не VirtualBox ли это. Но перед этим... шлёпнем ещё один зашифрованный блок!
    Расшифровываем его:


    [CODE]
    jmp @f
    db 0x99, 0xFE, 0xFF
    @@:
    lea rax, qword[RealCode_Start]
    @@:
    xor byte[rax], REAL_CODE_KEY

    lea rax, qword[rax+1]
    cmp rax, RealCode_END
    jne @b
    ...
    [/CODE]
    Далее передаём ему управление, и чистим все следы за собой.

    [CODE]
    xor rax, rax
    lea rdi, qword[Init_END]
    mov rcx, (HelpCode_END-Init_END)/8
    rep stosq
    [/CODE]Отлично, теперь память снова сломана. Это хорошо. Давайте же теперь начнём перечислять список процессов, и поищем там Vbox*, или q.exe (это скрытый процесс AnyRun):
    Перед этим инициализируем структуру PROCESSENTRY32:

    [CODE]
    jmp @f

    pe32:
    .dwSize dd 0
    dd 0
    dd 0
    rd 1
    dq 0
    dd 0
    dd 0
    dd 0
    dd 0
    dd 0
    .szExeFile rb 260
    sizeof.pe32 = $ - pe32
    @@:
    [/CODE]
    Ну и используем стандартные CreateToolhelp32Snapshot/Process32First/Process32Next/CloseHandle для поиска:

    [CODE]
    mov rcx, 0x2
    xor rdx, rdx
    call qword[FUNCTION_TABLE]
    mov r15, rax
    ; Сохраним дескриптор CreateToolhelp32Snapshot в r15

    mov dword[pe32], sizeof.pe32

    mov rcx, rax
    lea rdx, qword[pe32]
    call qword[FUNCTION_TABLE+1*8]

    @@:
    mov rcx, r15
    lea rdx, qword[pe32]
    call qword[FUNCTION_TABLE+2*8]
    test eax, eax
    jz @f

    cmp dword[pe32.szExeFile], 'q.ex'
    je fake_code

    cmp dword[pe32.szExeFile], 'VBox'
    je fake_code

    ; ... Todo more checks!

    jmp @b
    @@:
    [/CODE](Если это VirtualBox или AnyRun - прыгнуть на fake_code)
    Первая функция в таблице FUNCTION_TABLEэто CreateToolhelp32Snapshot, поэтому для неё не нужно никакое смещение, указатель уже установлен на неё.

    1*8 = вторая функция. Не забывайте, отчёт с нуля. Это Process32First
    Соответственно, 2*8 это Process32Next


    [CODE]
    mov rcx, r15
    call qword[FUNCTION_TABLE+3*8]
    ...
    [/CODE]Ну и вызываем CloseHandle (3-я функция в таблице).

    Хорошо, на AnyRun/VirtualBox проверили, теперь последний, 4-й зашифрованный блок кода!

    По той же технике, сначала расшифровываем уже зашифррованный код данной функции (если же это не AnyRun/VirtualBox):

    [CODE]
    lea rax, qword[SeriouslyRealCode_Start]
    @@:
    xor byte[rax], SERIOUSLY_CODE_KEY
    lea rax, qword[rax+1]

    cmp rax, SeriouslyRealCode_END
    jne @b
    ...
    [/CODE]
    И чистим память, все проверки, все расшифровки - в мусорку:

    [CODE]
    xor rax, rax
    lea rdi, qword[RealCode_Start]
    mov rcx, (RealCode_END-RealCode_Start)/8
    rep stosq
    ...
    [/CODE]
    И выходим на финишную прямую - вызываем MessageBoxA:

    [CODE]
    jmp @f
    userdll: db 'user32.dll', 0
    msgbox: db 'MessageBoxA', 0
    title: db 'LLCPPC finish work!', 0
    msg: db 'Example of protected code', 0
    @@:
    lea rcx, qword[userdll]
    call qword[LoadLibrary]

    mov rcx, rax
    lea rdx, qword[msgbox]
    call qword[GetProcAddress]

    sub rsp, 0x28
    xor rcx, rcx
    lea rdx, qword[msg]
    lea r8, qword[title]
    xor r9, r9
    call rax
    ...
    [/CODE]
    Зачищаем таблицу функций, чтобы никто не узнал, что за адреса там лежали, и что мы вызывали:

    [CODE]
    xor rax, rax
    lea rdi, qword[FUNCTION_TABLE]
    mov rcx, (FUNCTION_TABLE_NAMES-FUNCTION_TABLE)/8
    rep stosq
    [/CODE]
    Зачищаем код с вызовом MessageBoxA, и выходим

    [CODE]
    SeriouslyRealCode_noStart:
    xor rax, rax
    lea rdi, qword[SeriouslyRealCode_Start]
    mov rcx, (SeriouslyRealCode_noStart-SeriouslyRealCode_Start)/8
    rep stosq

    ret
    [/CODE]
    [CODE]
    ; ## ## #### ##### ##### ####
    ; ## ## ## ## ## ## ## ## ## ##
    ; ## ## ## ## ## ## ## ##
    ; ## ## ## ##### ##### ##
    ; ## ## ## ## ## ##
    ; ## ## ## ## ## ## ## ##
    ; ###### ###### #### ## ## ####
    ; 03.08.2015 - 03:23
    ; Malware Selector: /93##

    format PE64 GUI
    entry start


    INITIALIZATION_KEY = 0x90
    FUNCTION_TABLE_NAMES_KEY = 0x7F
    HELP_CODE_KEY = 0x6F
    REAL_CODE_KEY = 0x19
    SERIOUSLY_CODE_KEY = 0xEF

    section 'LLCPPC' import readable writeable executable
    dd 0, 0, 0, RVA kernel, RVA kernel_table

    kernel_table:
    GetProcAddress dq RVA _GetProcAddress
    LoadLibrary dq RVA _LoadLibraryA
    dq 0


    _GetProcAddress: dw 0
    db 'GetProcAddress', 0

    _LoadLibraryA: dw 0
    db 'LoadLibraryA', 0

    kernel: db 'kernel32.dll', 0

    align 8
    FUNCTION_TABLE:
    dq 6 dup(0)

    align 32
    FUNCTION_TABLE_NAMES:
    @@:
    db 'CreateToolhelp32Snapshot'
    times 32-($-@b) db 0
    @@:
    db 'Process32First'
    times 32-($-@b) db 0

    @@:
    db 'Process32Next'
    times 32-($-@b) db 0

    @@:
    db 'CloseHandle'
    times 32-($-@b) db 0

    @@:
    db 'ExitProcess'
    times 32-($-@b) db 0

    @@:
    db 'Sleep'
    times 32-($-@b) db 0

    @@:
    db 'GetTickCount'
    times 32-($-@b) db 0

    FUNCTION_TABLE_NAMES_END:

    encrypt FUNCTION_TABLE_NAMES, ($-FUNCTION_TABLE_NAMES), FUNCTION_TABLE_NAMES_KEY


    align 8

    start:
    lea eax, qword[Initialization]
    @@:
    jmp @f
    db 0x99, 0xFE, 0xEF
    @@:
    xor byte[eax], INITIALIZATION_KEY

    lea eax, qword[rax+1]

    jne @b

    Initialization:
    lea eax, qword[FUNCTION_TABLE_NAMES]
    @@:

    xor byte[rax], FUNCTION_TABLE_NAMES_KEY
    jmp .undefined_command
    db 0x7F, 0x9F, 0xEF
    .undefined_command:
    lea eax, qword[rax+1]

    cmp eax, FUNCTION_TABLE_NAMES_END
    jne @b



    lea rcx, qword[kernel]
    call qword[LoadLibrary]
    mov r13, rax
    lea r14, qword[FUNCTION_TABLE]
    lea r15, qword[FUNCTION_TABLE_NAMES]
    @@:
    mov rdx, r15
    mov rcx, r13
    call qword[GetProcAddress]

    mov qword[r14], rax

    lea r14, qword[r14+8]
    lea r15, qword[r15+32]

    cmp r15, FUNCTION_TABLE_NAMES_END
    jne @b

    cld
    lea rdi, qword[FUNCTION_TABLE_NAMES+8]
    mov rcx, (FUNCTION_TABLE_NAMES_END-FUNCTION_TABLE_NAMES)/8
    rep stosq

    lea rax, qword[HelpCode_Start]
    @@:

    xor byte[rax], HELP_CODE_KEY
    jmp .undef_instr
    db 0x9F, 0xFF, 0x0F, 0xEE
    .undef_instr:

    lea rax, qword[rax+1]
    cmp rax, HelpCode_END
    jne @b

    jmp HelpCode_Start+1
    Init_END:

    encrypt Initialization, (Init_END-Initialization), INITIALIZATION_KEY

    HelpCode_Start:
    lea rdi, qword[start]
    jmp @f
    db 0x99, 0xF0, 0xF5, 0xD0
    @@:
    mov rcx, (Init_END-start)/8
    jmp @f
    db 0xDD, 0xFE, 0xFF, 0x09
    @@:
    rep stosq


    call qword[FUNCTION_TABLE+6*8]
    mov r15, rax

    mov rcx, 2000
    call qword[FUNCTION_TABLE+5*8]

    call qword[FUNCTION_TABLE+6*8]
    sub rax, r15


    cmp rax, 2500
    jmp @f
    db 0x09, 0x90, 0xEE
    @@:
    jg fake_code

    db 0x99, 0xFE, 0xFF
    @@:
    lea rax, qword[RealCode_Start]
    @@:
    xor byte[rax], REAL_CODE_KEY

    lea rax, qword[rax+1]
    cmp rax, RealCode_END
    jne @b
    HelpCode_END:

    encrypt HelpCode_Start, (HelpCode_END-HelpCode_Start), HELP_CODE_KEY


    RealCode_Start:
    xor rax, rax
    lea rdi, qword[Init_END]
    mov rcx, (HelpCode_END-Init_END)/8
    rep stosq

    jmp @f

    pe32:
    .dwSize dd 0
    dd 0
    dd 0
    rd 1
    dq 0
    dd 0
    dd 0
    dd 0
    dd 0
    dd 0
    .szExeFile rb 260
    sizeof.pe32 = $ - pe32
    @@:


    mov rcx, 0x2
    xor rdx, rdx
    call qword[FUNCTION_TABLE]
    mov r15, rax

    mov dword[pe32], sizeof.pe32

    mov rcx, rax
    lea rdx, qword[pe32]
    call qword[FUNCTION_TABLE+1*8]

    @@:
    mov rcx, r15
    lea rdx, qword[pe32]
    call qword[FUNCTION_TABLE+2*8]
    jz @f

    cmp dword[pe32.szExeFile], 'q.ex'
    je fake_code

    cmp dword[pe32.szExeFile], 'VBox'
    je fake_code

    ; ... Todo more checks!

    jmp @b
    @@:


    mov rcx, r15
    call qword[FUNCTION_TABLE+3*8]

    lea rax, qword[SeriouslyRealCode_Start]
    @@:
    xor byte[rax], SERIOUSLY_CODE_KEY
    lea rax, qword[rax+1]

    cmp rax, SeriouslyRealCode_END
    jne @b
    RealCode_END:

    encrypt RealCode_Start, (RealCode_END-RealCode_Start), REAL_CODE_KEY

    SeriouslyRealCode_Start:

    xor rax, rax
    lea rdi, qword[RealCode_Start]
    mov rcx, (RealCode_END-RealCode_Start)/8
    rep stosq

    jmp @f
    userdll: db 'user32.dll', 0
    msgbox: db 'MessageBoxA', 0
    title: db 'LLCPPC finish work!', 0
    msg: db '2015 | Laser Malware Team forever!', 0
    @@:
    lea rcx, qword[userdll]
    call qword[LoadLibrary]

    mov rcx, rax
    lea rdx, qword[msgbox]
    call qword[GetProcAddress]

    sub rsp, 0x28
    xor rcx, rcx
    lea rdx, qword[msg]
    lea r8, qword[title]
    xor r9, r9
    call rax

    xor rax, rax
    lea rdi, qword[FUNCTION_TABLE]
    mov rcx, (FUNCTION_TABLE_NAMES-FUNCTION_TABLE)/8
    rep stosq

    SeriouslyRealCode_noStart:
    xor rax, rax
    lea rdi, qword[SeriouslyRealCode_Start]
    mov rcx, (SeriouslyRealCode_noStart-SeriouslyRealCode_Start)/8
    rep stosq

    ret

    SeriouslyRealCode_END:

    encrypt SeriouslyRealCode_Start, (SeriouslyRealCode_END-SeriouslyRealCode_Start), SERIOUSLY_CODE_KEY


    fake_code:
    xor rcx, rcx
    xor rbx, rbx
    xor rdx, rdx
    xor rax, rax
    @@:
    add rcx, rbx
    sub rcx, rdx
    mul rbx
    shl rax, 4
    add rax, rdx
    mov rax, rbx
    add rbx, 90
    cmp rbx, 0xF0
    cmove rax, rbx
    add rax, rcx
    sub rax, rdx
    ; ... write more!

    cmp rax, 0xDD
    jne @b

    ret
    [/CODE]


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

    Читайте так же:
    * Ревёрс-инжиниринг *******а RedLine -> https://zelenka.guru/threads/2866730/
    * Ревёрс-инжиниринг DC-RAT -> https://zelenka.guru/threads/2878088/
    * Ревёрс-инжиниринг *******а X-FILES -> https://zelenka.guru/threads/2884957/
    * Пишем полиморфный код на ассемблере с шифрованием (обход VirtualBox, AnyRun, дампа памяти, 5 блоков кода) -> https://zelenka.guru/threads/2881723/
    * Ревёрс-инжиниринг MarsStealer -> https://zelenka.guru/threads/2888161/
    * Ревёрс-инжиниринг SHurk Steal -> https://zelenka.guru/threads/2889104/
     
    22 авг 2021 Изменено
  2. CoderVir
    Хм. Годно.
     
  3. jgsjagejwgjwf
    какая-то твоя старая тима?
     
    1. LLCPPC_inactive4415647 Автор темы
      @backdoortp, Не моя, но раньше в ней был, писали на заказ и продавали шифровальщик для заражения серверов
      Забыл изменить текст сообщения
  4. vyvyvyoyvtvrvwww
    godno, spasibo
     
Top