Посоветуйте статьи по морфингу PE-шников. Можно на английском. Интересуют все шаги от начала и до конца. Когда я добавлял секцию в бинарник, оказалось, что между таблицей секций и секцией кода нет свободного места, поэтому новая секция залезла на .text. Насколько я понимаю, универсальный способ упаковки требует пересборки всего PE-файла. При морфинге код также может увеличиться в несколько раз, что потребует пересобрать PE-шник. Непонятно и то, как происходит замена одним инструкций на другие. Вроде, это похоже на конечный автомат, которому на вход подается инструкция, а на выходе получается блок рандомного выполнимого кода с исходной логикой. Буду рад любым мануалам. Еще я пишу простую виртуальную регистровую машину. Каким образом используются виртуальные машины при упаковке?
PE - всего лишь формат файла, заголовок, секции с таблицами. Если начало файла заморфить, его загрузчик системы не запустит. Import Adress Table можно самому воссоздать. Одним словом, я бы посоветовал задуматься, что есть что и для чего. Секция в адресном пространстве процесса со своими правами, где у тебя будут переписываться байты, где будешь морфить? в стэке, в куче, в своей секции? Может будешь использовать тот факт, что в интеле опкоды разной длины? ты просто пишешь по определенному адресу байты, а потом кидаешь туда RIP. Это как в книге расставляешь точки над некоторыми буквами, а потом читаешь только выделенные буквы, и вот у тебя свой рассказ в рассказе.
Вам нужно смотреть в сторону темы инфекта исполняемых файлов с той разницей, что при внедрении шифруется оригинальное тело, а при выполнении - расшифровывается и передается управление на старую точку входа. Статьи - можете почитать соотв. vx статьи, хоть Касперски того же (основы, например, есть в "Компьютерные вирусы изнутри и снаружи") . И http://z0mbie.daemonlab.org/ . А вообще - 'это классика, это знать надо' (c)
Концептуально, абстрактно я процесс криптования примерно представляю и писал свой упаковщик с LoadPE, сделанный как контейнер для PE-файла. Пока не нашел работу, разбирался с книгой Эриксона "Art of exploitation". Однако почти все мне все равно непонятно. Например, техническая сторона инфекта файлов. Когда я писал свой инфектор или разбирал сорсы с rohitab, он в большинстве случаев фейлился, потому что в PE-файле линкер не оставил места для нового заголовка секции. К таблице секций вплотную примыкала секция .text. Я делал инфект в code cave'ы. Без перестроки PE-шника не обойтись. Как это сделать? Если морфить секцию кода, размер этой секции сильно увеличится, и PE-файл придется перекраивать. Я хотел бы написать библиотеку на C++ для работы с PE-файлами в ООП-стиле, чтобы можно было загрузить файл в буффер, а потом просто вызывать методы класса для модификации этого файла, и в конце сбросить его на диск. Такой подход сработает? Да, инструкции интел разной длины. В таком случае каким образом разбить секцию кода на инструкции и заменить каждую инструкцию на блок мусора? Секция кода в памяти защищена от записи. Расшифровывать секции надо либо в буфере в хипе, либо вызывать VirtualProtect. Очень много вопросов...
Aoizora, Ты ничего не можешь морфить. Для этого у тебя нет инструмента. Он должен уметь выделять и пересобирать процедуры. Только затем следует билд целого модуля, но забудь про это - задача не решаема, тк данные не отличимы от кода. Для этого нужны спец маркеры, тут и тема есть по этой задаче. --- Сообщение объединено, 26 мар 2019 --- Aoizora, > Непонятно и то, как происходит замена одним инструкций на другие. Вроде, это похоже на конечный автомат Ты даже не понимаешь что есть морф. Вначале блок кода декомпилируется и создаётся его описание в виде графа. Там описываются линейные блоки и все ветвления. Далее с графом работает конструктор, это компилер, который из графа собирает машинный код. Сам же морф выполняется на абстрактном уровне, изменяется граф, выполняются вставки, рандомизация всякая и тп. Для этого нужен соответствующий инструмент и это никакого отношения к крипторам/протекторам/пакерам/загрузчикам не имеет. В последнем случае образ обрабатывается как единое целое, там нет понятия морфа. Так как он не возможен по многим причинам - не известны все EP, ссылки и размеры таблиц. --- Сообщение объединено, 26 мар 2019 --- Aoizora, Кстате чуть не забыл - морф единственный рабочий способ для установки патчей, особенно в 64(тк RIP-адресация). Для этого процедура переносится в буфер.
Нашел такую статью: https://vxlab.info/malware-trashgen/ Каким мог быть алгоритм trashgen, чтобы он создавал выполнимый мусор и при этом занимал 10-15 опкодов? Код (ASM): format PE GUI entry start include 'win32a.inc' section '.text' code executable start: call trashgen db 0x00, 0x00, 0x00, 0x00, 0x00 db 0x00, 0x00, 0x00, 0x00, 0x00 db 0x00, 0x00, 0x00, 0x00, 0x00 db 0x00, 0x00, 0x00, 0x00, 0x00 invoke MessageBoxA, 0, message, caption, 0 ret trashgen: mov edi, [esp] invoke VirtualProtect, edi, 512, 0x40, buffer mov ecx, 20 mov eax, 0x90 rep stosb ret section '.data' data readable writeable caption db "!!!", 0 message db "I'm alive!", 0 buffer dd 0 section '.idata' data readable import library kernel32, 'kernel32.dll',\ user32, 'user32.dll' import kernel32, ExitProcess, 'ExitProcess',\ VirtualProtect, 'VirtualProtect' import user32, MessageBoxA, 'MessageBoxA'
nopgen По-моему просто "выполнимый мусор" немного устарело уже. Некоторые новые (не будем показывать пальцем) дизасмы-декомпилеры прямо из коробки умеют находить инструкции, инициализирующие регистры/переменные неиспользующимися в дальнейшем значениями и автоматически их выкидывать из декомпиля. Даже если это довольно длинная цепочка вычислений, заканчивающаяся ничем, примешанная к основному алгоритму. --- Сообщение объединено, 26 мар 2019 --- И хуже того, в этих дизасмах можно и самому скриптом обработать p-код, сгенерированный по функции, обнаружив и пометив/выбросив инструкции, в которых все операторы относятся к такому ни к чему не ведущему мусору. Левой пяткой практически. Так что только простенькие и не очень интерпретаторы (виртуалки, а не мусор) могут чего-то противопоставить этому.
Необязательно мусор. Задача-то просто затруднить реверс/автоматический анализ. Просто с обфусцированным кодом совсем все уныло стало, когда он стал представлять интерес для крякеров.
f13nd, > Задача-то просто затруднить реверс/автоматический анализ. В виксах не так, это не верный подход. На мусоре строятся сигнатуры. Сам принцип всегда один - что то декриптуется, но данный процесс блокируется от виртуальной машины ав, иначе далее будет детект по распакованным данным/коду. Могут меняться части модуля, но они детектору не доступны - это всё криптовано. Сам же билд пе идея провальная, это никогда небыло реализовано, так что бы работало хоть как то. Те попытки как то формировать образ, которые в крипторах используются - это детские поделки, чистые сигнатуры. Задачу на голом пе решить невозможно принципиально. Но можно отлично всё реализовать на уровне билда, используя промежуточные данные компилера. Так как данные там есть все - ссылки, лимиты, описатели, короче всё что необходимо для сборки.
Что-то я задумался о виртуализации кода и придумал абстракцию vmcall для своей микровиртуалки, которая получает адрес кода, инициализирует VM и выполняет код. Когда решил погуглить vmcall, оказалось, что такая штуковина уже где-то придумана. https://stackoverflow.com/questions/27786602/does-vmcall-instruction-in-x86-save-the-guest-cpu-state
Aoizora, Тоесть у тебя как я понял ни вопроса ни задачи нет. Ты просто пришёл в новую для тебя область и для этого создал тему. Вначале нужно изучить что уже сделано за десятилетия. Нашёл в гугле инструкцию, а ман открыть не додумался. Таким сейчас мозг не нужен, гугл знает всё за вас.