Сейчас на форуме: UniSoft, laslo, bartolomeo (+5 невидимых) |
eXeL@B —› Программирование —› [Sources] ASProtect Virtual Machine for marker "UserPolyBuffer" |
Посл.ответ | Сообщение |
|
Создано: 22 сентября 2011 22:44 · Личное сообщение · #1 ..:: ASProtect Virtual Machine for marker "UserPolyBuffer" ::.. * Что это? * Это исходный код виртуальной машины, при компиляции дающий бинарник полностью бинарно- и форматно- совместимый с одной из виртуальных машин защиты исполняемых файлов ASProtect. Это значит, что переход в виртуальную машину ASProtect можно заменить на переход в получившуюся виртуальную машину и код интерпретируется правильно. Кроме того, любой примитив оригинальной виртуальной машины можно заменить примитивом получившейся и в этом случае тоже ошибки не будет. В исходном коде практически полностью восстановлен стиль программирования автора, большинство ошибок и недоработок. Самые абсурдные места я пометил комментарием "WTF?". Полученный бинарник тестировался на версии 2.58. * Цель * Очень многие не понимают сути виртуальной машины. Кому то просто интересен принцип работы. Кто то хочет посмотреть код виртуальной машины коммерческой защиты исполняемых файлов. В данном случае код будет интересен в первую очередь разработчикам программ, которые доверяют защиту, своего программного обеспечения протектору ASProtect. Т.е. цель - исключительно исследовательская, это не декомпилятор защиты, это именно исходный интерпретатор. * История * Данная виртуальная машина была впервые применена для сокрытия кода QuickVM. QuickVM - виртуальная машина, интерпретирующая всего 4 типа инструкций: call, jmp, jcc, cmp+jcc. Но на тот момент устройство QuickVM уже было полностью изучено и всё, чего добились разработчики ASProtect - это резкое снижение быстродействия всей защиты. Поэтому в следующем же билде эту виртуальную машину сняли с кода QuickVM. Но, т.к. виртуальная машина уже была реализована, то ее стали применять для маркеров UserPolyBuffer, установленных в коде приложения. Видимо для того, чтобы не придумывать новые маркеры, а может просто для тестирования. Но, спустя небольшой промежуток времени с маркеров UserPolyBuffer ее убрали и для защиты пользовательского кода не используют больше вообще. В виртуальной DLL ASProtect, что извлекается во время запуска защищенной программы в память, тоже используются маркеры UserPolyBuffer. Вот для них теперь и используется эта виртуальная машина, т.е. она теперь защищает функции самого ASProtect. * Благодарности * - ntldr За публикацию, пусть и для узкого круга людей, своего эмулятора. Его исходный код очень помог в понимании базовой логики процесса эмуляции процессорных команд и в частности понимания эмуляции некоторых, довольно сложных логически. - Ms-Rem За публикацию исходных кодов дизассемблера CadT. Его реализация очень похожа на реализацию функций декодирования инструкций в виртуальной машине ASProtect. Что дало понимание назначения битовых масок при разборе полей ModRM и SIB, и логики самих функций декодирования. - Archer За помощь в разборе исходных кодов C и C++, это единственный человек, который всегда отвечает на мои дебильные вопросы, касаемо данного языка программирования и которого я почему то всегда хочу забанить, когда мне грустно - ASPack Software За неиссякаемый источник головоломок, не дающий засохнуть уставшему мозгу. Скачать ----- Yann Tiersen best and do not fuck | Сообщение посчитали полезным: yagello, SaNX, YDS, daFix, Dart Sergius, ARCHANGEL, Fedonin, [Nomad], SReg, Gideon Vi, yanus0, OKOB, VodoleY, Isaev, Airenikus, Nightshade, Dart Raiden, Valemox, m0bscene, OnLyOnE, vnekrilov, DimitarSerg, VAD87, ClockMan, obfuskator, Smon, MarcElBichon, kioresk, Hexxx, ValdiS, _ruzmaz_, newborn, xmss |
|
Создано: 23 сентября 2011 23:21 · Личное сообщение · #2 |
|
Создано: 24 сентября 2011 05:30 · Личное сообщение · #3 |
|
Создано: 24 сентября 2011 12:22 · Личное сообщение · #4 |
|
Создано: 24 сентября 2011 12:36 · Личное сообщение · #5 |
|
Создано: 24 сентября 2011 13:06 · Поправил: bowrouco · Личное сообщение · #6 > это именно исходный интерпретатор. На спекки был мощный эмулятор и интерпретатор васика Это была первая ось, которую я изучал и с которой работал Там для вычисления тригонометрии использовались ряды маклорена и прочая матчасть, в конце концов сводилось к виртуальным инструкциям.. А аспаки на дельфях, флаи и прочие поделки както не серьёзно. |
|
Создано: 24 сентября 2011 13:50 · Личное сообщение · #7 Не серьезно - это древний эмулятор васика, давно забытый богом. А интерпретатор, а тем более декомпилятор, того, что используется сейчас и с чем имеешь дело почти каждый день - очень даже серьезно. SaNX пишет: было бы лучше, если б ты дописал Там нужно интерактив писать, что то типа иды для гавнопрота, это в мои планы не входило, поэтому притормозил, ибо под интерактив нужно полностью ядро переписывать. ----- Yann Tiersen best and do not fuck |
|
Создано: 24 сентября 2011 16:26 · Личное сообщение · #8 |
|
Создано: 24 сентября 2011 16:57 · Личное сообщение · #9 |
|
Создано: 25 сентября 2011 16:28 · Личное сообщение · #10 |
|
Создано: 25 сентября 2011 23:34 · Поправил: kioresk · Личное сообщение · #11 PE_Kill, kioresk не писал деморфер, он написал девиртуализатор. Не-не-не, деморфер для криптора просто долгое время лежал недоделанным. Я довел его до работающей версии недавно, но пока еще есть что улучшать. Например, сейчас нет встроенного ассемблера (автоматом восстанавливающего код), а формируется текстовая портянка для Multimate Assembler, которую надо ручками в Олле вставить и сдампить файл. Ну и еще много чего надо доделать. Кстати он обрабатывает только ~80% виртуализованных инструкций, как раз потому, что работает без деморфера. Не пойму о чем речь, какие виртуализованные инструкции девм не обрабатывает? Соотношение сложности написания девиртуализатора к деморферу примерно 1 к 100, вот и думай. 1 к 10 скорее, у криптора же не очень сложная реализация (обфускацию можно спокойно паттернами сворачивать). P.S. Я девм (восстановление релоков) поэтому все никак не доделаю, как время появлялось — допиливал деморф. P.P.S., Присоединяюсь к PE_Kill'у и также благодарю ntldr за его эмулятор. А еще респект mika0x65 за Mediana. | Сообщение посчитали полезным: vnekrilov, tihiy_grom |
|
Создано: 26 сентября 2011 00:39 · Личное сообщение · #12 PE_Kill пишет: Кстати он обрабатывает только ~80% виртуализованных инструкций, Насколько я понимаю, виртуализированные инструкции хорошо обрабатывает скрипт "EXECryptor 2.4.x DeVM (VolX).osc". Я применял его на одной программе, и он очень неплохо работает. VolX довольно хорошо разобрал виртуальную машину ExeCryptor, и приложил к своему скрипту фактически декомпилятор эмулированных инструкций, выполняемых в VM. Кроме того, этот скрипт очищает мусорный код, и делает его намного более читаемым. Хотя очень напрягает мусорный код с целой кучей прыжков и пустого кода, что затрудняет восстановление нормально-читаемого кода. |
|
Создано: 26 сентября 2011 12:55 · Личное сообщение · #13 kioresk пишет: портянка для Multimate Assembler, Возьми ассемблер от OllyDbg я везде его использую, после медианы нормально ассемблирует мнемонику. kioresk пишет: Не пойму о чем речь, какие виртуализованные инструкции девм не обрабатывает? Ну я проверял на больших файлов, не обрабатывал те, call которых ведет в пролог VM очень сильно разбавленных jcc, граф эдак на 50 ветвлений. kioresk пишет: криптора же не очень сложная реализация У меня сложность обработки в автоматическом режиме вызвало ветвление блоков кода, которые можно свернуть только отдеморфив обе ветки и сравнив оба блока ветвления, т.к. в этих блоках тоже есть ветвления а в подблоках еще и т.д. И второе это на автомате определять процедуры, которые вызываются линейно: Вместо @L1: some code call TestProc @L2: some code Морфится @L1: some code push offset @L2 тело TestProc ret @L2: some code Как опознать, что первый push это RetAddr я так и не придумал. ----- Yann Tiersen best and do not fuck |
|
Создано: 26 сентября 2011 23:14 · Поправил: Hexxx · Личное сообщение · #14 |
|
Создано: 26 сентября 2011 23:41 · Личное сообщение · #15 А в таком случае (реальный пример)?: Оригинальный код: ------------------------------------------------ mov ecx, offset VTable ; VTable = 0 call SomeProc @L: next code ------------------------------------------------ @SomeProc: push offset Param1 push offset Param2 call [ecx+4] retn ------------------------------------------------ После морфа: ------------------------------------------------ mov ecx, offset VTable ; VTable = 0 push offset @L @SomeProc: push offset Param1 push offset Param2 call [ecx+4] retn @L: next code ------------------------------------------------ Собственно когда я встретил это, я и притормозил разработку. ----- Yann Tiersen best and do not fuck |
|
Создано: 26 сентября 2011 23:57 · Поправил: kioresk · Личное сообщение · #16 PE_Kill, Возьми ассемблер от OllyDbg я везде его использую, после медианы нормально ассемблирует мнемонику. Спасибо, гляну. Ну я проверял на больших файлов, не обрабатывал те, call которых ведет в пролог VM очень сильно разбавленных jcc, граф эдак на 50 ветвлений. А, понял о чем ты. Так поиск точек входа в ВМ примитивный, поэтому может и не определять входы. Если у тебе «проблемный» файл остался — скинь мне, посмотрю. У меня сложность обработки в автоматическом режиме вызвало ветвление блоков кода, которые можно свернуть только отдеморфив обе ветки и сравнив оба блока ветвления, т.к. в этих блоках тоже есть ветвления а в подблоках еще и т.д. Да, эта часть у меня тоже не до конца сделана (деморф и сравнение веток не используется). Сейчас удаляются JCC, которые идут внутри обфуцирующих конструкций (когда ветвление всегда будет идти только по одному маршруту) и часть JCC, дублирующих граф (код). Дублирующие JCC легко определить когда она виртуализована (т.к. она имеет свой опкод в ВМ — 0x83). И второе это на автомате определять процедуры, которые вызываются линейно: ... Как опознать, что первый push это RetAddr я так и не придумал. Можно определять по обфуцирующей конструкции, т.к. вызов процедуры обычно идет так: push reg32_1 mov reg32_1, imm32_1 <-- обфуцировано xchg [esp], reg32_1 <-- пушим адрес выхода из процедуры push reg32_2 mov reg32_2, imm32_2 <-- обфуцировано xchg [esp], reg32_2 <-- пушим адрес начала процедуры ret <-- вызываем процедуру Но я на всякий случай запрашиваю у пользователя, похож ли код на вызов процедуры. |
|
Создано: 27 сентября 2011 00:59 · Личное сообщение · #17 |
|
Создано: 27 сентября 2011 03:04 · Личное сообщение · #18 Да какой оффтоп продолжайте дальше. все будут рады наконец-то дописанному деморфу | Сообщение посчитали полезным: Dart Raiden, vnekrilov, SReg, daFix |
|
Создано: 27 сентября 2011 08:50 · Личное сообщение · #19 |
|
Создано: 27 сентября 2011 13:26 · Личное сообщение · #20 |
|
Создано: 29 сентября 2011 13:52 · Личное сообщение · #21 |
|
Создано: 29 сентября 2011 14:48 · Личное сообщение · #22 Ну смотри как я делал. Берешь файл с API ASProtect и делаешь простенький проект, который берет из ASProtect HardwareID. Т.е. используешь GetHardwareID. Перед вызовом этой апи делаешь загрузку скомпилированной VM. И после этого втыкаешь int 3. Протектишь файл, загружаешь в OllyDbg, жмешь F9 и останавливаешься на int 3. Всё дальше трассируешь код, уходя в GetHardwareID и там то ли на первом то ли на втором call увидишь навешанную VM, даешь ей положить параметры в стек, заходишь в call жмешь Ctrl+G, вбиваешь VmPrologue и Enter. Ставишь туда Eip и можешь трассировать. Лучше скомпилить VM с map файлом, тогда оля будет показывать названия всех функций. Проект что то типа того: LoadLibrary('PBVM.dll'); asm int 3 end; sHwid := GetHardwareID(); ----- Yann Tiersen best and do not fuck |
eXeL@B —› Программирование —› [Sources] ASProtect Virtual Machine for marker "UserPolyBuffer" |