Msg : Prev 1685 / 4681 Next +1690
From: Reminder
1996-11-28 22:24:16

To  : All

Subj:

нечто ;))


Привет All! 

Короче, народ, я решил тут сделать faq ;)) 

Кто найдет ошибки - пусть сюда и пишет, вместе что-то и 
изобразим. А то эха я смотрю вовсе загнивает :(( 

;-------------------------------------------------------------------------- 
Вопрос 1: 

PC> Слушай, объясни, как работают полиморфики ? 
PC> Я так понимаю, что берут команды типа 
PC> mov ax,5 
PC> и заменяют на что-то типа 
PC> push cx 
PC> xor cx,cx 
PC> inc cx ; *!* 
PC> xhcg ax,cx 
PC> add ax,4 ; *!* 
PC> pop cx 
PC> Или вроде того. Ессесьно, каждый раз команды типа *!* меняются 
PC> на другие. 
PC> Или я не прав ? 

ну что то в этом роде. в общем классический полиморфик строится так: 

1) декриптор 
2) зашифрованное тело 

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

mov ax,kod 
mov si,offset 
mov cx,len 

@1: 
xor [si],ax 
inc si 
inc si 
loop @1 

как мы можем его изменить так, чтобы по маске его уже было не выловить. 

- Первое. мы видим первые три команды, от перестановки которых местами в 
любом порядке результат не изменится. Следовательно мы можем их менять 
местами. 
- Второе: мы видим постоянные регистры используемые в данном декрипторе, 
как то - ax,cx,si. 
Мы можем их изменить на другие. si например, как регистр индексный мы 
можем поменять на di,bx,bp, то есть другие индексные регистры. 
ax например на любой не задействованный в декрипторе. 
cx не можем изменить, но посредством замены кода мы можем избавиться от 
этой жесткой привязки (см. ниже) 
Так вот, все регистры мы можем менять. все встречающиеся команды с 
использованием регистра, который мы меняем мы меняем тоже соответственно. 
- Третье: мы можем добавить в код некоторые дополнительные команды, которые 
по сути не играют роли в исполнении, но присутствуют затем, чтобы как можно 
более размыть маску. допустим однобайтовые: nop,cld,cmc... и такое подобное. 
двухбайтовые: adc dx,bx; sub bx,ax, трехбайтовые: mov xx,[любое 16 битовое 
значение] ну и так далее. В этом контексте надо использовать все регистры 
которые _незадействованы_ в твоем декрипторе. то есть если вдруг ты 
используешь в декрипторе ax,si,cx то в полиморном мусоре ты используешь все 
остальные. 
- Четвертое: как ты уже сказал взаимозаменение действующих команд. ты в 
принципе 
сам ответил на этот вопрос. 
добавлю немного что вот loop @1 ты мог бы заменить на dec cx,jnz @1 или 
cmp si,offset конца декриптуемого кода и jbe @1 или jb @1 , в зависимости если 
ты переставишь местами si и оffset то выйдет уже jae @1 или ja. 
если декриптор большой и не влазит в 128 байт то формируй что-то вроде: 

cmp si,offset_of_end 
jbe @2 
jmp @1 ; всместо jmp можно использовать mov xx,@1 и jmp xx (xx - это 
неиспользуемый регистр) 
@2: 
Короче - это твоя фантазия как это сделать ;)) 

- Пятое - частично производное из четвертого: команды раскриптовщика как то - 
xor мы можем заменить на sub,add например. 

соответственно декриптовщик строится в соответствии с криптовщиком. 
соответствие должно проводится по - ключам раскриптовщика и методам 
раскриптовки (add,sub,xor). 

- Шестое - мы можем использовать несколько скелетов раскриптовщиков. 
например первый, который раскручивает линейно и просто по одному коду. 
мы можем написать также раскриптовщик который декриптует прыжками по телу 
раскриптовываемого кода. также мы можем (в примитиве) менять ключ 
раскриптовщика динамически. Hапример между командочками inc si и inc si 
мы можем вставить add ax,bx или sub ax,bx. соответственно в начале 
мы должны вставить команду mov bx,kod2. 

Стоит ли говорить, что kod,kos2,offset,len - это всегда разные значения. 

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

mov ax,kod 
> ^^ 
..... 
xor [si],ax 
> ^^ 

регистры одиннаковы. :( статистически можно выявить их и декриптовать 
основываясь на этом. А это плохо. В противодействие этому между этими 
командами мы можем вставить такой код: 

mov dx,ax или xchg ax,dx или xchg dx,ax 

соответственно код поменяется: 

mov ax,kod 
... 
mov dx,ax 
... 
xor [si],dx <- и тут уже dx вместо ax. 
если преобразований поставить несколько, например: 
mov ax,kod 
... 
xchg dx,ax 
... 
mov bp,dx 
... 
xchg bp,di 
... 
xor [si],di 
то проследить будет уже не так легко как прежде. 
естественно - поскольку действующие регистры меняются динамически, то 
уже неиспользуемые регистры используются в полиморфном мусоре. 
например вот такой код: 
mov dx,kod 
... 
mov ax,dx 
... 
mov dx,[что нибудь левое] 
... 
xchg bp,ax 
... 
add ax,cx ; портим ax 
... 
xchg bx,bp 
... 
xor bp,ax ; портим bp 
... 
... 
xor [si],bx 
p.S. Hу вот для начального ознакомления вроде бы все. Я не рассказал тебе 
еще построений левых условных переходов, левых процедур и такое прочее. 
но надеюсь что пока тебе это не понадобится ;)) 
в любом случае ты _сам_ можешь многому научиться 
поизучав SMEG,MtE и другие классические вещи. 
И еще запомни - не надо слепо копировать эти приемы, надо придумывать самому 
- так гораздо интереснее, полезнее и приятнее. :) 
Писалось все это дело в страшной спешке, посему возможно есть несколько 
неточностей, хотя я не думаю :) 
;--------------------------------------------------------------------------- 
С бестовыми регардами , Kostya Volkov aka Reminder 
.' [SGWW] [DVC] [Crematorium fans Team] [MK Team] `. 
--- 
* Origin: Kostya Volkov aka Reminder (2:4631/17) 
VX Heavens - коллекция вирусов,исходников и статей.
Длинный список? Alt + Home - в начало, Alt + End - в конец
Пользовательского поиска