PDA

Просмотр полной версии : собственно новичкам про крипторы


dokzlo13
05.11.2010, 00:01
Ну во первых не видел на форуме статей о написании криптора. Да и в интернете их мало, везде отрывочные знания и предложения. Во вторых много копался по этому поводу, но написать нормальный криптор так и не вышло. Поэтому в этой теме будем только пробовать, кто что знает помогайте и дополняйте, может чего и получится ))

Нынче стали модны пакеры и крипторы exe/dll файлов. Не стану объяснять, зачем они нужны, а перейду сразу к делу. Сегодня я при тебе напишу самый простой exe-криптор. Как всегда, самым примечательным в моей статье будет крайний примитивизм. А второго ее качества, надеюсь, никто не заметит =).
на борту
Я предпологаю, что все, что ты имеешь - это прямые руки, навык кодить на Delphi и самые поверхностные понятия об ассемблере.
Первым делом тебе предстоит ознакомиться со структурой exe-файлов [Ссылки доступны только зарегистрированным пользователям]

Итак, теперь ты знаешь, как устроены exe-шники. Теперь я вкрадце опишу наш план.
план
В исполняемых файлах нас больше всего интересуют PE-заголовок, таблица секций и секция кода.
Как будет работать наш криптор?
Сначала заполненная часть секции кода будет зашифрована. Поскольку мы пишем простой криптор, то "шифровать" он будет простым not'ом.
В конец кода мы запишем крохотный декриптор, который этот самый код расшифрует и передаст ему управление.
Тут есть 2 момента. Во-первых, при запуске программы должен начинать работать не шифротекст, а декриптор. Поэтому нам придется изменить Entry Point в PE заголовке. А во-вторых, так просто изменять код бинарников нам никто не даст. При запуске программы вся секция кода помещается в память. Вот там мы изменим код программы. Чтобы мы могли писать в секцию кода, необходимо изменить ее Object Flag.

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

push 12345678
ret

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

Как ты заметил, размер каждой секции выровнен относительно File Align. Значит в секции кода, скорее всего, есть немного места для декодера. Мы не будем расширять секцию кода, а значит у екзешника даже не измениться размер.

Двойной клик по семерке с глобусом
Вкурил? ^_^ Приступим к реализации вкрадце описанного мною плана.
Как будет внедряться код?
Сначала следует изменить PE заголовок и элемент таблицы секции, описывающий секцию кода (как правило самый первый элемент). Мы добавляем код, следовательно его размер измениться.

inc(PEModuleHeader.Size_of_Code,sizeof(CryptCode)) ;
inc(SectionTable.Virtual_Size,sizeof(CryptCode));

Затем вспоминаем, что мы собираемя модифицировать код в процессе работы программы:

SectionTable.Object_Flags:=SectionTable.Object_Fla gs or $80000000;

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

STVirtSize:=SectionTable.Virtual_Size;
PEModuleHeader.Entry_Point_RVA:=PEModuleHeader.Bas e_of_Code+STVirtSize;

Определяемя с функцией шифрования:

function crypt(b:byte):byte;
begin
result:=not b;
end;

Мы должны прочитать бинарник до начала кода.
Затем зашифровать код. Затем вставить прямо за ним дешифровщик. Как он выглядит:

mov ecx, 0xddccbbaa; помещаем в ecx длинну зашифрованного кода
call 0 ; вызываем следующую команду
pop eax ; помещаем в eax адрес текущей команды
push 0xddccbbaa ; помещаем в стек старую точку входа
sub eax,14 ; вычисляем адрес конца шифротекста
not byte ptr [eax]; "шифруем"
dec eax ; переходим к предыдущему байту
loop $-3 ; в начало цикла
ret ; переходим в старый Entry Point

Вот тут скорее всего возникнет масса вопросов.

Сначала мы помещаем в регистр ecx длину шифротекста. Затем вызываем инструкцию, смещенную относительно данной на ноль байт, то есть следующую. Что нам это дало - при выполнении инструкции call в вершину стека помещается адрес следующей команды. Затем мы извлекаем этот самый адрес, теперь уже текущей команды, в регистр eax. Помещаем в стек адрес старой точки входа - зачем - чуть ниже.
Мы вычитаем из eax длину вышестоящих команд, таким образом теперь в eax записан адрес конца шифротекста, ведь декодер следует прямо за ним.
Мы инвентируем байт по адресу [eax], то есть последний байт шифротекста. Уменьшаем eax на единицу, то есть теперь в нем записан адрес предпоследнего байта шифротекста. loop -3 - переходим к инструкции not byte ptr [eax]. При этом из ecx вычитается единица.
Цикл будет повторяться до тех пор, пока не обнулиться ecx, то есть, пока весь код не будет расшифрован. Ты еще помнишь, что в ecx записанна длина кода?
Затем выполниться инструкция ret. При этом управление передастся в точку с адресом, записанным в вершину стека. Если ты помнишь, туда мы записали старую точку входа. То есть сразу после дешифровки управление передастся расшифрованному коду программы.

© drmist

Ещё выкладываю пару исходников крипторов на делфи:
[Ссылки доступны только зарегистрированным пользователям]
[Ссылки доступны только зарегистрированным пользователям]

Вот ещё неплохие исходники + программа.
На C++ [Ссылки доступны только зарегистрированным пользователям]
НА Delphi [Ссылки доступны только зарегистрированным пользователям]

источник [Ссылки доступны только зарегистрированным пользователям]

maulo
20.11.2010, 21:59
Вся схема очень запутана,:blink: я пробивал написать по вашим исходнику неполучилось, появилось много вопросов которие необговорение в етой стате, бил би я очень рад если би ви виложили видео к мануалу ...

fgmed
22.11.2010, 15:17
а если создать на вашем исходнике будет палиться антивирусами?

hz_kto_ya
23.11.2010, 10:20
Автор перезалей исходники плиз!
To fgmed: конечно будет.

master008
23.11.2010, 21:25
В статье описаны самые самые основы. Но именно это лучший вариант криптора а не через грёбанный writeprocessmemory.

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