Сейчас на форуме: (+9 невидимых) |
eXeL@B —› Протекторы —› Декомпилятор ВМ |
<< . 1 . 2 . 3 . 4 . 5 . 6 . 7 . 8 . 9 . 10 ... 23 . 24 . >> |
Посл.ответ | Сообщение |
|
Создано: 03 марта 2010 12:33 · Личное сообщение · #1 Вашему вниманию предлагаются наработки по декомпиляции ВМ. Проект на сегодняшний день для меня завершен, но жаль если результат "ляжет на полку", может кому-нибудь и пригодится. Предлагаю сначала ознакомиться с обзором, и если будет интерес то могу выложить и сам плагин, или здесь или в личку заинтересованным лицам, каким образом, пока ещё не решил... Но если кто-либо ожидает увидеть "автоматическое чудо", то сразу скажу - его нет. Для того чтобы получить результат нужна ручная предварительная работа: - с исследуемой программы должна быть снята упаковка - точки входа в ВМ находятся вручную - возможно неоднократное "жамкание" клавиш в OllyDbg, а возможно и модификация кода, чтобы попасть в нужное место, в зависимости от защищенной функции - необходимо вручную прицепить к программе требуемый секцию - запись результатов в файл это тоже ручная работа, но уже более приятная Не всё гладко обстоит с определением реализаций ВМ, на сегодняшний день примерно каждая третья реализация автоматом не определяется, приходится под неё модернизировать плагин, т.к. не могу сразу предусмотреть все случаи "издевательств" ВМ с кодом примитивов. Лучше дела с восстановлением "исходного" кода защищенных функций - 70% нормально восстанавливается, хотя во многом это зависит от самой структуры функции. Таким образом, если будет заинтересованность и помощь в нахождении подобных ситуаций, то проект может быть доведен до релизной стадии. ЗЫ: Речь идет об Ореановских машинах. Нигде специально не упоминал. 9c41_03.03.2010_CRACKLAB.rU.tgz - VMSweeperLst.rar ----- Everything is relative... |
|
Создано: 18 марта 2010 15:42 · Поправил: Vamit · Личное сообщение · #2 Заканчиваю написание деобфускатора апишных вызовов применительно к этому. на входе имеем, вернее при создании этого кода уже "удалены" вызовы call, jmp и jcc Code:
на выходе получил Code:
что делать дальше вроде бы понятно, но есть вопросы (задаю в скобках) - найти съеденную IAT (можно ли это автоматизировать? или отдать юзеру, пусть сам ищет и вводит границы в предлагаемую форму?) - найти в IAT секцию для kernel32 (каким образом, если она будет вообще пустой?) - записать на свододное место секции адрес функции Sleep, адрес записи перенести в команду mov edi, [addr] - записать восстановленную команду на своё родное место - запись изменений в файл (большой вопрос - на данном этапе ВМ с распаковки файла ещё не снята, импорт не восстановлен, стаб то же, следовательно записать в файл ничего не можем, как поступить в этом случае?) ----- Everything is relative... |
|
Создано: 18 марта 2010 18:01 · Поправил: DillerInc · Личное сообщение · #3 Vamit пишет: следовательно записать в файл ничего не можем, как поступить в этом случае? ...выделяешь память размером с секцию кода, копируешь туда саму секцию и все изменения вносишь в эту память,высчитывая смещение: instr VA - code section VA == offset | temp mem VA + offset == instr in temp mem VA Я считаю, что подобный подход необходим всегда, ибо протектор может запросто проверять определённые метки во время выполнения своих процедур расчёта импорта, краденных инструкций и т.п. ----- the Power of Reversing team |
|
Создано: 18 марта 2010 20:11 · Личное сообщение · #4 Vamit пишет: найти съеденную IAT (можно ли это автоматизировать? или отдать юзеру, пусть сам ищет и вводит границы в предлагаемую форму?) Обычно сначала заполняется табличка, отловить GPA прота не сложно да и проще сначала заполнить табличку по загружаемым библам чем раскидывать кашу при трейсе , а затем правит вызовы в сответствии с табличкой. |
|
Создано: 19 марта 2010 14:15 · Поправил: Vamit · Личное сообщение · #5 |
|
Создано: 21 марта 2010 11:25 · Личное сообщение · #6 Vamit пишет: как в Ольке проверить на валидность начало какой-либо инструкции? т.к. ответа нет, отвечу сам Code:
вот только не знаю, насколько это решение полное... ----- Everything is relative... |
|
Создано: 23 марта 2010 19:42 · Личное сообщение · #7 |
|
Создано: 24 марта 2010 08:41 · Личное сообщение · #8 Обновил VMSweeper, добавлено: - анализ всех точек входа в ВМ с отображением статуса - восстановление съеденного импорта, в том числе и структуры IAT Эти две функции по идее могут работать с любыми типами ВМ, подопытный "кролик" d8be_23.03.2010_CRACKLAB.rU.tgz - VMSweeper1_2beta.rar ----- Everything is relative... |
|
Создано: 24 марта 2010 13:14 · Личное сообщение · #9 |
|
Создано: 24 марта 2010 13:26 · Личное сообщение · #10 |
|
Создано: 24 марта 2010 16:02 · Поправил: Vamit · Личное сообщение · #11 daFix пишет: Восстановление импорта тестировалось только на ВМпроте? Да, на том что было в наличии... kioresk пишет: лучше убери шаманство с добавлением к файлу секции .vm, ибо все протекторы с нормальной ВМ всегда проверяют контрольную сумму файла лучше, чем что...? ладно, это лирика. во-первых секция цепляется уже к распакованному файлу, который запускается и работает, так что CRC здесь не причем, на дампе она не проверяется. во-вторых, она нужна для декомпиляции тела ВМ в промежуточный код, что можешь предложить взамен? Пока нужно где-то 64Кб, но возможно и больше в зависимости от длины кодированного участка функции, причем код в ней должен быть рабочим с вызовом из тела восстанавливаемой функции. После восстановления фунции(й) эта секция больше не нужна. ----- Everything is relative... |
|
Создано: 24 марта 2010 16:47 · Личное сообщение · #12 во-первых секция цепляется уже к распакованному файлу, который запускается и работает, так что CRC здесь не причем, на дампе она не проверяется. Если файл не надо будет предварительно распаковывать, то это облегчит жизнь реверсера (минус одна операция). во-вторых, она нужна для декомпиляции тела ВМ в промежуточный код, что можешь предложить взамен? Пока нужно где-то 64Кб, но возможно и больше в зависимости от длины кодированного участка функции, причем код в ней должен быть рабочим с вызовом из тела восстанавливаемой функции. Могу предложить VirtualAllocEx. |
|
Создано: 24 марта 2010 17:03 · Личное сообщение · #13 |
|
Создано: 24 марта 2010 17:07 · Поправил: Vamit · Личное сообщение · #14 kioresk пишет: то это облегчит жизнь реверсера (минус одна операция). Если реверсер не сможет распаковать файл, то это уже не реверсер - ему и дальше делать нечего... А вы хотите, чтобы декомпилятор ещё и файл полностью распаковал..., нет, таких задач я не ставил. kioresk пишет: Могу предложить VirtualAllocEx Проверено, не работает, для работы эту память должна видеть Олька, а не только плагин, а Олька к сожалению видит только то, что пристегнуто к файлу. ----- Everything is relative... |
|
Создано: 24 марта 2010 17:09 · Личное сообщение · #15 Vamit пишет: А вы хотите, чтобы декомпилятор ещё и файл полностью распаковал..., нет, таких задач я не ставил. Декомпилятор это средство для декомпиляции. Не надо требовать распакованности файла, равно как и требовать от него распаковку. Vamit пишет: Проверено, не работает, для работы эту память должна видеть Олька, а не только плагин, а Олька к сожалению видит только то, что пристегнуто к файлу. В контексте программы не пробовали сделать VirtualAllocEx? |
|
Создано: 24 марта 2010 17:24 · Поправил: Vamit · Личное сообщение · #16 progopis пишет: В контексте программы не пробовали сделать VirtualAllocEx? Да всё пробовал, вся беда в том, что плагин может вносить изменения только после того как файл загружен в Ольку, но, после того как он уже загружен (EIP на точке входа), к нему ничего Олькой не добавить. Память должна видеться не программой, а именно Олькой, как контекст программы. Был ещё один вариант: сделать пустую dll загрузить в систему, а затем из Ольки выполнять на неё переход, не получилось, т.к. чтобы её увидела Олька она должна быть в импорте. А что пихать Dll в импорт, что добавлять секцию к файлу - равнозначно, но второе проще, поэтому выбрал этот вариант. Пока эта секция не мешает, но уже сейчас подхожу к ситуации, когда она нужна, а её ещё нет: восстановление съеденного стаба. Для анализа входов в ВМ и восстановления импорта она не нужна, но чтобы завершить распаковку файла нужно встать на OEP или близко к ней и запустить декодирование стаба (пока работать без секции не будет), и только затем можно сохранить дамп и получить рабочий файл. ----- Everything is relative... |
|
Создано: 24 марта 2010 17:40 · Личное сообщение · #17 Vamit пишет: к нему ничего Олькой не добавить И как же тогда OllyDbgScript работает? Надо взять контекст программы, изменить ESP, в стэк засунуть параметры VirtualAllocEx, EIP переставить на VirtualAllocEx, не забыв в качестве адреса возврата бряк воткнуть, в выделенную память можно запихнуть любой управляющий код (а можно и сразу ВМ), после чего весь мусор убирается, если он был, а EIP возвращается на точку входа. |
|
Создано: 24 марта 2010 17:50 · Поправил: kioresk · Личное сообщение · #18 Если реверсер не сможет распаковать файл, то это уже не реверсер - ему и дальше делать нечего... А вы хотите, чтобы декомпилятор ещё и файл полностью распаковал..., нет, таких задач я не ставил. Вопрос не о знаниях реверсера (читай крутости), а об упрощении задачи и как следствие — экономии времени. Да всё пробовал, вся беда в том, что плагин может вносить изменения только после того как файл загружен в Ольку, но, после того как он уже загружен (EIP на точке входа), к нему ничего Олькой не добавить. Память должна видеться не программой, а именно Олькой, как контекст программы. Можно попробовать так: 1. забэкапить кусок кода на текущем EIP (c помощью Readmemory из SDK) 2. вставить туда шеллкод (c помощью Writememory из SDK), в котором будет вызываться VirtualAllocEx, а результат будет помещаться по оффсету EIP+xyz 3. далее шагам по шелкоду (или ставим бряк в конце и запускаем до бряка) 3. затем считываем результат из EIP+xyz, если там не ошибка — работаем с ним 4. восстанавливаем затертый кусок кода и значение EIP Добавлено progopis опередил, да еще и с более простым решением. |
|
Создано: 24 марта 2010 20:30 · Личное сообщение · #19 |
|
Создано: 25 марта 2010 09:26 · Поправил: Vamit · Личное сообщение · #20 Проведя небольшой анализ VMProtect (до точки вызова обработчиков примитивов) выявил следующие отличия в его ВМ по сравнению с Ореановскими ВМ: 1. Инициализация ВМ (конечная точка – вход в цикл интерпретатора ВМ) Code:
2. Интерпретатор ВМ (конечная точка – вызов обработчика примитива) Code:
Выводы: 1. Реализовать в декомпиляторе один обработчик разных типов ВМ проблематично, но это и к лучшему. Проще под каждый тип ВМ сделать собственный обработчик на едином алгоритме, чем делать «солянку» в одном обработчике, по крайней мере, добавление обработчика нового типа ВМ не нарушит работу уже существующих. 2. Понятен общий принцип определения типа ВМ декомпилятором (сейчас он представляет из себя набор «жестких»условий, но на самом деле это не так): - найти точку входа в цикл интерпретатора ВМ при статическом анализе точки входа в ВМ из тела функции. - выявить анализатором моменты указанные в таблице 1 - дойти статическим анализом до точки вызова обработчика примитива - выявить анализатором моменты указанные в таблице 2 - подтвердить моменты таблицы 1 - определить алгоритм хеширования кода примитива - определить алгоритм хеширования адреса обработчика примитива А далее, после определения типа ВМ, идем по уже пройденной дорожке: - идентифицируем обработчики примитивов ВМ - «заменяем» интерпретатор ВМ с обработчиками примитивов промежуточным кодом и т.д., что уже было описано и реализовано ранее… ----- Everything is relative... |
|
Создано: 25 марта 2010 13:25 · Поправил: Vamit · Личное сообщение · #21 Вернусь к старому вопросу с VirtualAllocEx, не получается так как надо с динамической памятью: память выделяется, Олька её видит, но в процессе декомпиляции выполняются рестарты программы и даже исключения в ней, затем принудительный рестарт - во всех этих случаях выделенный сегмент автоматом удаляется, если же создавать новый, то его адрес получается в большинстве случаев разный, следовательно код ассемблированный под определенный ip уже в этом сегменте не работает. ----- Everything is relative... |
|
Создано: 26 марта 2010 11:29 · Личное сообщение · #22 |
|
Создано: 26 марта 2010 12:30 · Личное сообщение · #23 mak пишет: Работа с Bin файлом не подходит? Не понял, причем здесь bin файл, мне нужно не просто хранилище кода, на это добро и памяти хватает, а реально рабочий код, который добавляется к проге и который можно реально дебажить в Ольке в одном контексте с программой и который "не разрушается" при перезагрузке проги в Ольке. Фактически он, конечно, разрушается, но копия лежит у меня в памяти, а так как под него в проге отведен статический сегмент, то при перезагрузке проги он просто копируется из памяти в этот сегмент. ----- Everything is relative... |
|
Создано: 26 марта 2010 13:12 · Личное сообщение · #24 Vamit сложно подсказать что-то конкретное не зная деталей, если бы приаттачил пример кода, размещаемого в этой памяти, и описал немного какая идет привязка между этой промежуточной областью и кодом жертвы, то было бы проще. А так, думаю, ты и сам понимаешь, что только базовонезависимый код поможет в этом случае. |
|
Создано: 26 марта 2010 13:16 · Личное сообщение · #25 mak пишет: хучить вылетание ольги , и запоминать что было последнее не задумывался почему в линуксе до сих пор нет корректного работающего hibernate (спящий режим)? Нет? Ну удачи. На хороших ВМ такой метод свалится на простейшей антиотладке. mak пишет: можно вносить куски кода временные переменные это на каком языке написано? Vamit пишет: который можно реально дебажить в Ольке в одном контексте с программой а зачем его дебажить? можно вообще не вязаться к ольке, а делать тулзу которая будет читать всё что нужно из памяти программы через ReadProcessMemory. Если уж очень сильно надо всё делать в ольке, надо разбираться почему происходят вылеты. Это явно либо некорректная работа декомпилятора, либо непрозрачность режима отладки (нарушение условий выполнения программы). Писать софт на костылях не имеет смысла. Хватает уже. |
|
Создано: 26 марта 2010 14:17 · Поправил: Vamit · Личное сообщение · #26 kioresk пишет: сложно подсказать что-то конкретное не зная деталей Всем все детали выложены в обзоре и самом инструменте, и чтобы предметно разговаривать необходимо хотя-бы попробовать его работу - много вопросов и не нужных советов отпадут, а повторять то, что уже сказано, я не хочу. только базовонезависимый код поможет в этом случае. Промежуточный код не может быть базонезависимым, пример его есть в обзоре. progopis пишет: а зачем его дебажить? Юзеру, если этот код правильный, то конечно, незачем. Вспомним это Vamit пишет: Не всё гладко обстоит с определением реализаций ВМ, на сегодняшний день примерно каждая третья реализация автоматом не определяется, приходится под неё модернизировать плагин, т.к. не могу сразу предусмотреть все случаи "издевательств" ВМ с кодом примитивов. , т.ч. дебажить нужно мне и может быть тому кто хочет полностью восстановить съеденное тело функции, но декомпилятор пока в некоторых случаях это сделать не может. Промежуточный же код 100% получается рабочим. progopis пишет: можно вообще не вязаться к ольке, а делать тулзу которая будет читать всё что нужно из памяти программы Можно, но нужен ассемблер + дизассемблер + дебаггер, которые сам я писать не собираюсь, в обзоре обоснован выбор инструмента. progopis пишет: Если уж очень сильно надо всё делать в ольке, надо разбираться почему происходят вылеты. Да тут и так всё понятно, если прочитать обзор и хелп. Если с произвольного места программы переместить ip на New origin here и давануть F9, то вы должны предсказать что будет... Или другой пример, программа идет через семафор (условный переход) а мы принудительно переходим его в другое направление, которое может быть обработкой исключения... progopis пишет: Писать софт на костылях не имеет смысла. Хватает уже. А костылей здесь нет, то что сидит в плагине независимо от кода программы, поэтому с ней можно делать всё что захочется, а плагин будет просто за этим наблюдать и собирать нужную инфу, главное саму Ольку не перегружать. ----- Everything is relative... |
|
Создано: 26 марта 2010 14:34 · Поправил: Модератор · Личное сообщение · #27 Vamit пишет: нужен ассемблер + дизассемблер + дебаггер, которые сам я писать не собираюсь Разве это проблема? Ассемблер может быть, но вот дизасм движки хорошие уже написаны, прекрасно подходящие для задач RE. Наиболее хорошие примеры UDIS и Mediana. Есть ещё metasm, но не сильно изучал его на юзабельность (там есть ассемблирование вроде). С отладчиками сложнее, но если не сильно волнует проблема отсутствия UI, то движков существует огромное мн-во, в том числе наш (который пока ещё не отлажен до конца, но тем не менее написан и работает). Я не просто языком здесь трещу, у нас есть рабочий декомпиль который работает по этому принципу. Отладчика там нет, только декомпиляция и деобфускация. |
|
Создано: 26 марта 2010 14:49 · Личное сообщение · #28 progopis пишет: Разве это проблема? Нет, это не проблема, но если есть наиболее легкий путь, то почему его не использовать? В Ольке есть всё, что мне необходимо и даже больше, чем надо... progopis пишет: в том числе наш (который пока ещё не отлажен до конца, но тем не менее написан и работает). А можно где-нибудь с вашим ознакомиться? ----- Everything is relative... |
|
Создано: 26 марта 2010 15:19 · Личное сообщение · #29 |
|
Создано: 02 апреля 2010 12:35 · Поправил: Vamit · Личное сообщение · #30 В продолжение к посту (Таблица 1) привожу реальные слепки регистров и стека полученные декомпилятором на точке входа в цикл ВМ (сама точка так же распознается декомпилятором самостоятельно), для двух типов ВМ: 1. VMProtect regs Code:
stack Code:
2. Ореановские ВМ regs Code:
stack Code:
отсюда видно, что распознать тип ВМ автоматически достаточно просто... ----- Everything is relative... |
|
Создано: 06 апреля 2010 20:17 · Личное сообщение · #31 Почитал доку . Весь пикод хэширован определенным образом, ключом хэширования является адрес размещения пикода в памяти. Неверно с созданием сигнатурного шаблона каждого примитива Неверно Необходимость предпоследней операции будет обоснована ниже. Неверно то в нем ищется первый условный переход за пределы этого блока Обрадую вас, в вмпротект нет условных переходов, вообще. Что будете делать? Рассказать об алгоритмической сложности задачи перебора всех возможных состояний? Вывод: с мат. частью проблемы. Хорошие идеи есть и их очень много, но не уверен, что идеи авторские. |
<< . 1 . 2 . 3 . 4 . 5 . 6 . 7 . 8 . 9 . 10 ... 23 . 24 . >> |
eXeL@B —› Протекторы —› Декомпилятор ВМ |