Оригинальный DVD-ROM: eXeL@B DVD !
eXeL@B ВИДЕОКУРС !

Видеокурс программиста и крэкера 5D 2O17
(актуальность: декабрь 2O17)
Свежие инструменты, новые видеоуроки!

  • 400+ видеоуроков
  • 800 инструментов
  • 100+ свежих книг и статей

УЗНАТЬ БОЛЬШЕ >>
Домой | Статьи | RAR-cтатьи | FAQ | Форум | Скачать | Видеокурс
Новичку | Ссылки | Программирование | Интервью | Архив | Связь


Распаковка ExeCryptor 2.3.9 (на примере PrevedSMS 5.1), часть 3




Массу крэкерских инструментов, видеоуроков и статей вы сможете найти на видеокурсе от нашего сайта. Подробнее здесь.

Обеспечение работы дампа ExeCryptor на разных операционных системах


Если мы попытаемся запустить исправленный файл dumped_.exe на другой операционной системе, то он не запустится. Почему это происходит?


Причина заключается в том, что при запуске программы, о чем я писал во второй части статьи, пакер записывает хэши реальных адресов API в свою область памяти. Когда программа вызывает эту API во второй раз, она проверяет наличие хэша этой API в заданной ячейке, и использует этот хэш для получения реального адреса API. Если же хэша нет в заданной ячейке (в ней записано 00000000), то пакер вычисляет реальный адрес этой API, вычисляет ее хэш, и записывает его в свою ячейку области памяти. Когда мы снимаем дамп памяти программы, остановленной на WOEP, пакер уже вычислил к этому моменту базовые адреса используемых DLL, а также определил хэши некоторых APIs, которые записал в свои ячейки памяти. Поскольку начальные адреса одних и тех же APIs в разных операционных системах отличаются друг от друга, то, при вызове программой этих APIs, хэши которых записаны в ячейках памяти пакера, генерируется сбой при запуске программы, поскольку раскриптованных адресов данных APIs нет в этой операционной системе.


Здесь очевидным является и путь решения этой проблемы. Если у нас в ячейках памяти секции пакера, куда записываются хэши APIs, будут записаны нули, то программа заново будет вычислять хэши APIs для данной операционной системы, и программа нормально запустится. В своей статье, EvOlUtIoN предлагает сделать два дампа распакованной программы на двух компьютерах, на которых установлены разные операционные системы. После этого, он предлагает выполнить сравнение этих дампов, и, с помощью специальной программы, которую он написал, выполнить замену значений хэшей на нули в ячейках области памяти пакера. Этот путь, на мой взгляд, более громоздкий, поскольку эту работу можно сделать намного проще. Просто необходимо сдампировать область памяти пакера .prot2, до момента записи в ней значений хэшей APIs (когда в них записаны исходные нули), и вставить дамп этой области памяти в файл dumped_.exe.


Загружаем упакованную программу в отладчик, и программа останавливается на TLS Callback. Секция пакера, которую мы в нашем файле dumped_.exe назвали .prot2 (она расположена непосредственно под секцией .rsrc), пока заполнена нолями. Удаляем временную BP, установленную отладчиком, и устанавливаем на эту секцию BMP on write:


Распаковка ExeCryptor 2.3.9: статья 3


Нажимаем клавишу F9, и программа останавливается здесь:


Распаковка ExeCryptor 2.3.9: статья 3


Здесь мы видим цикл распаковки секции .prot2. На выходе из цикла распаковки устанавливаем BP, удаляем BMP on write, и нажимаем клавишу F9. Следует отметить, что сама подпрограмма распаковки этой секции пакера довольно большая, и, если мы прокрутим ее код вниз, то увидим несколько инструкций RETN, последняя из которых и завершает распаковку кода секции .prot2:



Распаковка ExeCryptor 2.3.9: статья 3


Поэтому удаляем BMP on write, устанавливаем BP на инструкцию RETN, которая расположена по адресу 00DCE23A, нажимаем клавишу F9, и получаем распакованную секцию криптора. Но здесь выполнена только первая часть распаковки этой секции криптора. Если мы снова установим BMP on write на эту секцию криптора, и нажмем клавишу F9, то программа останавливается здесь:


Распаковка ExeCryptor 2.3.9: статья 3


При выполнении этого цикла, пакер корректирует адреса прыжков в области памяти .prot2. Поэтому удаляем установленную BMP on write, устанавливаем BP на инструкцию POP ECX, и нажимаем клавишу F9. После выполнения этого цикла, если мы опять установим BMP on write на эту область памяти, то можем посмотреть, как записываются по заданным адресам базовые адреса библиотек DLLs, и хэши разных APIs. Поэтому, можно сделать следующий вывод:


После остановки программы на инструкции POP ECX, которая находится по адресу 00B81167, можно сделать дамп памяти этой области пакера, и заменить им код в секции .prot2 файла dumped_.exe.



Для выполнения дампа этой области памяти, выделяем ее всю, и сохраняем ее, на всякий случай, с помощью Hex Workshop с именем Recovery_prot2, как это мы делали раньше:


Распаковка ExeCryptor 2.3.9: статья 3


Теперь, во втором отладчике мы открываем файл dumped_.exe, выделяем всю область памяти секции .prot2, и выполняем бинарную вставку:


Распаковка ExeCryptor 2.3.9: статья 3


Сохраняем сделанные изменения в файле, и пытаемся запустить доработанный файл dumped_.exe. Получаем следующее сообщение об ошибке:


Распаковка ExeCryptor 2.3.9: статья 3


Опять сработала анти-отладочная ловушка. Загружаем файл dumped_.exe в отладчик, и устанавливаем Hardware BreakPoint on access на API CreateThread. Нажимаем клавишу F9, чтобы запустить программу, и программа останавливается на начале API CreateThread:


Распаковка ExeCryptor 2.3.9: статья 3


Создание потока защиты с адресом ThreadFunction = 00641A4A у нас уже было, и мы заменили ранее инструкцию PUSH EBP инструкцией RETN. Нажимаем несколько раз клавишу F9, и программа останавливается здесь:


Распаковка ExeCryptor 2.3.9: статья 3


Переходим на адрес 00B6FB4D, и заменяем инструкцию PUSH EBP инструкцией RETN:


Распаковка ExeCryptor 2.3.9: статья 3


Сохраняем эти изменения, перезагружаем, файл в отладчике OllyDbg, и нажимаем клавишу F9 до тех пор, пока программа не остановится на API CreateThread с адресом начала потока защиты 00B6FB4D. Теперь устанавливаем Hardware BreakPoint on access на API WaitForSingleObject, и нажимаем клавишу F9. Программа останавливается на API WaitForSingleObject:


Распаковка ExeCryptor 2.3.9: статья 3




Нам надо определить, в каком же месте по адресу 0012FF14 записывается значение FFFFFFFF. Перезагружаем программу в отладчике, удаляем Hardware BreakPoint on access на API WaitForSingleObject (Hardware BreakPoint on access на API CreateThread остается установленной), и нажимаем клавишу F9. После остановки программы на API CreateThread, в окне dump переходим на адрес 0012FF14, и устанавливаем на него Hardware BreakPoint on write → Dword, как это мы делали ранее, во второй части статьи. Нажимаем клавишу F9 до тех пор, пока по адресу 0012FF14 не запишется значение FFFFFFFF:


Распаковка ExeCryptor 2.3.9: статья 3


Заменяем инструкцию MOV EDX,-1, которая находится по адресу 00B79805, инструкцией MOV EDX,0, чтобы параметр Timeout был равен 0, и тем самым устраняем бесконечное ожидание API WaitForSingleObject подтверждения об активности потока защиты, созданного API CreateThread. Сохраняем эти изменения в файле, перезагружаем программу в отладчике, и нажимаем клавишу F9, и нет ничего; т.е. программа не запускается. Опять загружаем программу в отладчик, нажимаем клавишу F9, и в строке состояния мы видим:


Распаковка ExeCryptor 2.3.9: статья 3

Распаковка ExeCryptor 2.3.9: статья 3


Возникает очевидный вопрос, почему дамп с записанными хэшами APIs в секцию пакера - запускается, а дамп с не записными хэшами APIs - не запускается? Очевидно, что в этой секции еще имеются какие-то изменения, которые не позволяют запустить нам программу, а показывают обнаружение отладчика - код [305]. Можно предположить (а это мы видели при удалении потоков защиты), что пакер, при запуске дампа программы с записанными хэшами APIs, заменяет какую-то инструкцию потока защиты инструкцией RETN. Но как найти эту инструкцию RETN? Я решил ее найти следующим образом. Открываем наш файл с исправленной секцией пакера, проходим на эту секцию, и выбираем команду поиска всех инструкций RETN:


Распаковка ExeCryptor 2.3.9: статья 3


Полученный список содержит 5360 адресов, ручная обработка которых займет много времени, и будет весьма трудоемкой. Поэтому облегчим себе жизнь, и выполним сравнение двух списков инструкций RETN - с исправленной и неисправленной секциями пакера. Для этой цели будем использовать утилиту Hex Workshop:



Распаковка ExeCryptor 2.3.9: статья 3


Вставляем полученный список в Hex Workshop:


Распаковка ExeCryptor 2.3.9: статья 3


Сохраняем полученный файл с именем Листинг RETN в исправленной секции пакера.


Повторяем то же самое действие для дампа dumped_.exe с неисправленной секцией пакера, и сохраняем полученный файл с именем Листинг RETN в неисправленной секции пакера.


Теперь загружаем оба Листинга в утилиту сравнения Hex Workshop, и выполняем их сравнение:


Распаковка ExeCryptor 2.3.9: статья 3




Получаем 20 несовпадающих адресов (вместо 5360!). При проверке этих адресов выяснилось, что часть этих адресов в исправленной секции пакера не содержат код (заполнены нолями), еще часть адресов содержат байты C3 в других инструкциях (JMP, MOV, и т.д.), и для проверки у нас остается только три адреса:


  00B23A36    51              PUSH ECX
  00B33D8A    68 B7F5F9F2     PUSH F2F9F5B7
  00B6ECA5    0F84 7949FAFF   JE 00B13624
  


Поочередно проверяем эти три адреса, и второй адрес является тем самым искомым адресом:


Распаковка ExeCryptor 2.3.9: статья 3


Сохраняем изменения в файле dumped_.exe, и программа нормально запускается как без отладчика, так и в отладчике:


Распаковка ExeCryptor 2.3.9: статья 3


Пока все идет хорошо, но у нас остался еще один момент. При прохождении на WOEP, пакер вычисляет и записывает базовые адреса используемых DLLs, и хэши некоторых APIs. Мы, в нашем дампе устранили записанные хэши APIs заменой всего кода секции пакера, но не устранили ссылки на базовые адреса DLLs.


Для решения этой проблемы, Haggar предложил очень хороший метод. Загружаем наш файл dumped_.exe в отладчик OllyDbg, и проходим на начало секции пакера .prot2. Выбираем команду “Search for All commands”, и вводим поиск следующей инструкции:


Распаковка ExeCryptor 2.3.9: статья 3



С помощью этой инструкции пакер проверяет наличие записанного базового адреса DLLs, и, если базовый адрес DLL не записан, то пакер вычисляет базовый адрес этой DLL (как он это делает, мы видели во второй части статьи). Нажимаем кнопку “Найти”, и получаем небольшой листинг этой инструкции:


Распаковка ExeCryptor 2.3.9: статья 3


Как видим, нам нужно обнулить значения только двух адресов - 00AE8924 и 006337F0. Переходим в окно dump отладчика, и делаем эти изменения:


Распаковка ExeCryptor 2.3.9: статья 3


Сохраняем изменения, и запускаем программу. Программа нормально запускается.


На моей машине установлена вторая операционная система Windows ME. Я скопировал файл dumped_.exe в папку программы PrevedSMS, установленную в этой операционной системе, и запустил его. Программа нормально запустилась. Поэтому, можно считать, что мы обеспечили работу распакованного файла на любой операционной системе.


6. Механизм работы ExeCryptor при выполнении украденных инструкций


Как мы видели ранее, пакер ExeCryptor ворует инструкции из кода программы, и выполняет их в своей секции. При этом пакер ворует инструкции не только из области OEP, но он также ворует инструкции и из других областей кода. Возникает вопрос - можно ли найти и восстановить из секции пакера украденные инструкции? Вопрос этот довольно не простой, поскольку код секции пакера разорван огромным числом условных и безусловных прыжков, и большим числом мусорного кода, что сильно затрудняет анализ кода протектора.


Для анализа кода протектора я исходил из следующей предпосылки: поскольку необходимый код инструкции, требуемой для работы программы, находится в закриптованном виде, то пакер должен сначала раскриптовать код этой инструкции, записать его в каком-то месте, и, затем, выполнить этот код. Ясно, что записывать раскриптованный код пакер будет в своей секции (мы это видели при раскриптовке реальных адресов APIs, базовых адресов DLLs).


Во второй части статьи мы восстановили код OEP, используя знание стандартного начала OEP компилятора Delphi, и значений регистров. Этот код был следующим:


Распаковка ExeCryptor 2.3.9: статья 3


Здесь пакер украл три инструкции, и, давайте рассмотрим, как пакер эмулирует выполнение этих инструкций. Сначала давайте, когда программа остановлена на Entry Point пакера, запишем значения регистров, поскольку пакер, при упаковке программы, обеспечивает сохранение начальных значений регистров:


Распаковка ExeCryptor 2.3.9: статья 3


Подавляем потоки защиты, запускаем упакованную программу в отладчике и ждем, пока не появится заставка программы. После этого проходим в окне dump на адрес 0012FFC0, устанавливаем на этом адресе Hardware BreakPoint on write, и нажимаем кнопку “Evaluate”. Программа останавливается здесь:


Распаковка ExeCryptor 2.3.9: статья 3


Программа остановилась после записи значения FFFFFFFF по адресу 0012FFC0. Теперь переходим в окно памяти, и устанавливаем BPM on write на секцию пакера, которая расположена под секцией .rsrc:




Распаковка ExeCryptor 2.3.9: статья 3


Это позволит нам определить, что записывает пакер в свою секцию. Нажимаем клавишу F9, и смотрим, что запишет пакер в свою секцию.


  006506D6    F0:8710         LOCK XCHG DWORD PTR DS:[EAX],EDX
  


Пакер выполняет обмен значений содержимого регистра [EAX] и регистра EDX.

Было - [00AE5150] = 00, EDX = 01. Стало: [00AE5150] = 01, EDX = 00.


Будем устанавливать BP на все инструкции записи в эту секцию пакера, поскольку эти инструкции могут повторяться несколько раз.


  00AFAC71    C700 00000000   MOV DWORD PTR DS:[EAX],0
  


Восстанавливается содержимое регистра [EAX]. Было [00AE5150] = 01. Стало: [00AE5150] = 00.


  00B18AA5    F0:0FC12D 708BB LOCK XADD DWORD PTR DS:[B28B70],EBP
  

Обмен значений содержимого [00B28B70] и регистра EBP, при этом к значению содержимого [00B28B70] добавляется значение регистра EBP.

Было - [00B28B70] = 64B2, EBP = 01. Стало: [00B28B70] = 64B3, EBP = 64B2.

  00B0BAB9    F0:0FB0A2 808BB LOCK CMPXCHG BYTE PTR DS:[EDX+B28B80],AH
  

Сравнение с обменом значений регистра AH и содержимого адреса [EDX+B28B80].

Было - [00B28C66] = 00, AH = 01. Стало: [00B28C66] = 01.

  00B09028    8F85 E84BB300   POP DWORD PTR SS:[EBP+B34BE8]          ; 0012FFF0
  

Запись значения 0012FFF0 в адрес [EBP+B34BE8] = [00B34EAC] с помощью инструкции POP. Желтым цветом я буду выделять известные нам начальные значения регистров, при остановке программы на Entry Point пакера (посмотрите на верхний рисунок); в данном случае - регистра EBP.

  00B09AA6    89BD F04FB300   MOV DWORD PTR SS:[EBP+B34FF0],EDI      ; ntdll.7C910738
  

Сохранение значения регистра EDI = 7C910738 по адресу [EBP+B34FF0] = [00B35388]; в данном случае сохраняется начальное значение регистра EDI.

  00B09AB2    89B5 FC53B300   MOV DWORD PTR SS:[EBP+B353FC],ESI
  

Сохранение значения регистра значение регистра ESI = FFFFFFFF по адресу [EBP+B353FC] = [00B35794]; в данном случае сохраняется начальное значение регистра ESI.


Далее идет группа из четырех инструкций, где сохраняются значения регистров EDX, ECX, EBX и EAX:

  006453ED    8995 1C2EB200   MOV DWORD PTR SS:[EBP+B22E1C],EDX
  006453F3    898D 142AB200   MOV DWORD PTR SS:[EBP+B22A14],ECX
  006453F9    899D 2432B200   MOV DWORD PTR SS:[EBP+B23224],EBX
  006453FF    8985 1426B200   MOV DWORD PTR SS:[EBP+B22614],EAX
  

По адресу [EBP+B22E1C] = [00B231B4] сохраняется значение регистра EDX = 00153CC0, по адресу [EBP+B22A14] = [00B22DAC] - значение регистра ECX = 00000012, по адресу [EBP+B23224] = [00B235BC] - начальное значение регистра EBX = 7FFD9000, и по адресу [EBP+B22614] = [00B229AC] - значение регистра EAX = 00AE5100.


Сохранение значения регистра ESP производится через его предварительную запись в регистр EAX:

  00645405    8BC4            MOV EAX,ESP
  

И, затем, значение регистра EAX = ESP сохраняется с помощью инструкции:

  00645407    8985 0422B200   MOV DWORD PTR SS:[EBP+B22204],EAX
  

По адресу [EBP+B22204] = [00B2259C] записывается значение регистра EAX = ESP = 0012FFC4.

  00B7509E    8985 0858B300   MOV DWORD PTR SS:[EBP+B35808],EAX
  

Здесь по адресу :[EBP+B35808] = [00B35BA0] сохраняется значение регистра EAX = 17C00500.

  00B10E71    870C24          XCHG DWORD PTR SS:[ESP],ECX
  

Производится обмен значения содержимого регистра [ESP] и значения регистра ECX.

Было: ECX = 0012FFF0, [0012FFC0] = 00000000. Стало: ECX = 00000000, [0012FFC0] = 0012FFF0.

Таким методом пакер эмулирует инструкцию PUSH EBP.

  00B10E74    83AD 0422B200 0 SUB DWORD PTR SS:[EBP+B22204],4
  

По этому адресу записано значение [EBP+B22204] = [00B2259C] = 0012FFC4, которое является начальным значением регистра ESP. Теперь это значение уменьшается на 4, что указывает пакеру на выполнение им инструкции PUSH, и устанавливает вершину стека по адресу 0012FFC0.




Таким методом пакер восстановил новое значение регистра ESP. Здесь мы видим, что сначала пакер последним сохраняет значение регистра ESP, и теперь он первым восстанавливает новое значение регистра ESP. Если мы посмотрим в окно стека, то там увидим следующее:


Распаковка ExeCryptor 2.3.9: статья 3

  00B3DC2A    C680 808BB200 0 MOV BYTE PTR DS:[EAX+B28B80],0
  

По адресу [EAX+B28B80] = [00B28C66] = 01 записывается 0. Эта инструкция показывает, что пакер успешно выполнил инструкцию PUSH EBP, и восстановил все сохраненные значения регистров, о чем мы можем убедиться, если посмотрим в окно регистров:


Распаковка ExeCryptor 2.3.9: статья 3

  00B475BA    F0:0FC12D 708BB LOCK XADD DWORD PTR DS:[B28B70],EBP
  

Обмен значений содержимого [00B28B70] и регистра EBP, при этом к значению содержимого [00B28B70] добавляется значение регистра EBP.

Было - [00B28B70] = 64B3, EBP = 01. Стало: [00B28B70] = 64B4, EBP = 64B3.


Зачем это нужно пакеру? Как мы видели выше, пакер использует значение регистра EBP для вычисления адреса, где он будет сохранять значения регистров. Поскольку при выполнении некоторых инструкций программы меняются значения регистров (например, при выполнении инструкции PUSH EBP изменяется адрес вершины стека), то новые значения регистров пакер записывает по новым адресам, добавляя 1 к значению константы в регистре EBP.


Далее повторяется цикл сохранения регистров по новым адресам, что очень хорошо видно, поскольку мы установили BP на инструкции сохранения значений регистров.

  00B099AD    8913            MOV DWORD PTR DS:[EBX],EDX      ; 00602C4C
  

В содержимое адреса EBX - [00B22630], записывается значение регистра EDX = 00602C4C.


  00AFC49C    C680 808BB200 0 MOV BYTE PTR DS:[EAX+B28B80],0
  

Опять по адресу [EAX+B28B80] = [00B28B87] = 01 записывается 0. Эта инструкция показывает, что пакер успешно выполнил инструкцию MOV EBP,ESP, и восстановил все сохраненные значения регистров.

  00AE379D    F0:0FC12D 708BB LOCK XADD DWORD PTR DS:[B28B70],EBP  
  

Обмен значений содержимого [00B28B70] и регистра EBP, при этом к значению содержимого [00B28B70] добавляется значение регистра EBP.

Было - [00B28B70] = 64B4, EBP = 01. Стало: [00B28B70] = 64B5, EBP = 64B4.


И опять повторяется цикл сохранения регистров.

  00AE765A    8985 2436B200   MOV DWORD PTR SS:[EBP+B23624],EAX        ; 00B33240
  

По адресу [00B238C0] записывается значение регистра EAX = 00B33240.

  00B28B64    0195 2436B200   ADD DWORD PTR SS:[EBP+B23624],EDX
  

Значение регистра EDX = 00000000 складывается со значением, хранимым по адресу [00B238C0].

  00B59DE4    C680 808BB200 0 MOV BYTE PTR DS:[EAX+B28B80],0
  

Опять по адресу [EAX+B28B80] = [00B28C27] = 01 записывается 0. Эта инструкция показывает, что пакер успешно выполнил вычисление промежуточного хэша для значения регистра ECX, и восстановил все сохраненные значения регистров.

  00B7B1A5    8903            MOV DWORD PTR DS:[EBX],EAX
  

По адресу [00B22D30] записывается значение регистра EAX = 4E05F6E5.

  00AE3179    C680 808BB200 0 MOV BYTE PTR DS:[EAX+B28B80],0
  

Опять по адресу [EAX+B28B80] = [00B28C47] = 01 записывается 0. Эта инструкция показывает, что пакер успешно выполнил вычисление окончательного хэша для значения регистра ECX, и восстановил все сохраненные значения регистров.


И, при очередном нажатии на клавишу F9, программа останавливается здесь (я здесь установил Hardware Break Point on access):


Распаковка ExeCryptor 2.3.9: статья 3



Далее выполняется основной код программы PrevedSMS.


Очень интересно посмотреть, как пакер восстанавливает сохраненные значения регистров. Если мы, после сохранения регистров, немного потрассируем пакер, то очень быстро найдем инструкции, которые применяются для восстановления сохраненных значений регистров.

  Регистр ESP восстанавливается с помощью этой инструкции:
 
00637F02 8BE0 MOV ESP,EAX
Регистр EBX восстанавливается с помощью этой инструкции:
00AE85D5 8B9D 2432B200 MOV EBX,DWORD PTR SS:[EBP+B23224]
Регистр EDX восстанавливается с помощью этой инструкции:
00B5C5B5 8B12 MOV EDX,DWORD PTR DS:[EDX]
Регистр EAX восстанавливается с помощью этой инструкции:
00B5C5B7 8B85 1426B200 MOV EAX,DWORD PTR SS:[EBP+B22614]
Регистр ECX восстанавливается с помощью этой инструкции:
00B4D5AA 8B09 MOV ECX,DWORD PTR DS:[ECX]
Регистр ESI восстанавливается с помощью этой инструкции:
00B2CF98 8B36 MOV ESI,DWORD PTR DS:[ESI]
Регистр EDI восстанавливается с помощью этой инструкции:
00B0B2CC 8B3F MOV EDI,DWORD PTR DS:[EDI] ; ntdll.7C910738
Регистр EBP восстанавливается с помощью этой инструкции:
00B3DC24 8B6D 00 MOV EBP,DWORD PTR SS:[EBP]

Здесь я привел адреса инструкций для восстановления сохраненных значений регистров при выполнении первой инструкции PUSH EBP. Для восстановления сохраненных значений регистров при выполнении инструкций MOV EBP,ESP и MOV ECX,7, применяются те же самые инструкции, но расположенные по другим адресам. Поэтому легко можно найти все инструкции для восстановления сохраненных значений регистров, выполнив поиск всех инструкций, например:


Распаковка ExeCryptor 2.3.9: статья 3


И в окне ссылок мы получаем:


Распаковка ExeCryptor 2.3.9: статья 3


Мы можем установить BP на каждую инструкцию, и остановить программу при восстановлении сохраненного значения любого регистра.

Теперь нам ясен механизм работы пакера при выполнении украденных инструкций:


  1. Сначала пакер вычисляет константу для регистра EBP с помощью инструкции LOCK XCHG DWORD PTR DS:[EAX],EDX (здесь, в этой статье, начальная константа для регистра EBP имеет значение 64B2; она изменяется при каждом запуске программы).

  2. Затем пакер сохраняет значения регистров в своей секции, используя константу регистра EBP для вычисления адреса хранения значений регистров. Например, для сохранения значения регистра EDX, пакер использует инструкцию MOV DWORD PTR SS:[EBP+B22E1C],EDX.

  3. Далее пакер раскриптовывает и выполняет украденную инструкцию.

  4. После выполнения украденной инструкции пакер восстанавливает значения регистров, которые не изменяются при выполнении данной украденной инструкции. Например, для восстановления значения регистра EDX, пакер использует инструкцию MOV EDX,DWORD PTR DS:[EDX].

  5. После восстановления всех значений регистров, пакер использует инструкцию MOV BYTE PTR DS:[EAX+B28B80],0, чтобы приступить к выполнению следующей эмулированной инструкции


Возникает один закономерный вопрос: а зачем нам это надо? Дело в том, что, используя знание механизма работы пакера ExeCryptor при выполнении украденных инструкций, и, наблюдая за процессом восстановления регистров с одновременным просмотром кода в окне стека, мы можем полностью восстановить не только код OEP, но и весь украденный пакером код. Это особенно полезно при восстановлении кода OEP, который всегда лучше выполнять в секции кода программы. А, используя выше приведенный алгоритм работы пакера, можно восстановить все украденные инструкции на их родное место.


7. Заключение


Эта статья оказалась довольно сложной в написании, и заняла у меня много времени. За время написания статьи, RSI разработал два очень хороших инструмента для работы с программами, упакованных ExeCryptor: Unpacker ExeCryptor 2.x.x. version 1.0 beta1 и ExeCryptor Dumper v2.0 beta. Эти инструменты значительно облегчают процесс распаковки программ, упакованных ExeCryptor. Однако, по отзывам, которые помещают cracker’s на сайте CRACKL@B, можно сделать вывод о том, что эти прекрасные инструменты не всегда успешно работают. Имеются программы, которые не распаковываются этими инструментами.


Поэтому, ручной процесс распаковки, который я описал в этой статье, может быть оказаться полезным при распаковке таких программ.


Мне хотелось бы поблагодарить модераторов форума CRACKL@B, которые помещают мои статьи, а также участников форума bronco, RSI, Gideon Vi, kioresk, r99, pavka и всех остальных участников форума за обсуждение разных аспектов распаковки этого криптора.


vnekrilov



Скачать статью "Распаковка ExeCryptor 2.3.9 (на примере PrevedSMS 5.1), часть 3" в авторском оформление + файлы.



Оригинальный DVD-ROM: eXeL@B DVD !


Вы находитесь на EXELAB.rU
Проект ReactOS