Введение в крэкинг с нуля, используя OllyDbg - Глава 52

Дата публикации 25 июл 2010

Введение в крэкинг с нуля, используя OllyDbg - Глава 52 — Архив WASM.RU



Конкурс завершился, но из-за его трудности в нем приняли участие немногие. Однако победитель всё же объявился — им стал Hiei, написавший скрипт для восстановления CALL’ов в крэкми ASProtect из предыдущей части.

Хотелось бы отметить, что многие ASProtect’овые анпэкми не работают в отладчике даже с установленным плагином Olly Advanced, поскольку при включении драйвера Anti-RDTSC программа работает не на всех компьютерах, а без него анпэкми и вовсе отказывается выполняться. Я заметил, что в последней версии ASProtect’а, примененной в нескольких программах, данная защита не установлена и такие программы в OllyDbg работают нормально. По крайней мере, я еще не видел программ, использующих ее и нуждающихся в Anti-RDTSC для своей работы. Вероятно, это связано с проблемами совместимости, и данная защита снята полностью или ее использование сокращено до минимума из-за ее крайней проблематичности.

У кого же драйвер RDTSC Olly Advanced функционирует нормально, те могут легко дойти до OEP, а затем запустить скрипт, приложенный к данному туториалу.

Это OEP, но при попытке запустить скрипт Hiei выдается сообщение, что установленная версия OllyScript устарела и ее надо обновить, поэтому пришлось искать новую, которая теперь называется ODbgScript. Этот проект продолжает развивать Epsylon, так как его первый автор SHaG больше им не занимается.

Скопируйте в папку с плагинами приложенную к статье DLL’ку:

А затем перезапустите Olly и снова дойдите до OEP. Не забудьте деактивировать Break-on-execute, иначе из-за него возникнут проблемы.

Хотя это всего лишь новая версия OllyScript’а, в меню отображаются оба плагина, поэтому следует выбрать новый и в нем открыть скрипт Hiei:

Сразу же после запуска запрашивается адрес, на который направляют проблемные CALL’ы, — на моем компьютере это 19A0000:

После нажатия на OK скрипт начинает свою работу, а немного позже наблюдаем результат:

На скриншоте показан CALL, который раньше указывал на 19A0000 (так на моем компьютере), а теперь он восстановлен вместе со всеми остальными. Hiei вполне справился с поставленной задачей, поздравляю!

Вот скрипт, содержащий комментарии самого автора, а далее привожу мои собственные:

Код (Text):
  1.  
  2. -----------------------------------------------------------------------------------------------------------------
  3. /*
  4. -=============================================================-
  5. .:[CracksLatinoS]:.
  6.     Автор скрипта: Hiei
  7.     Назначение: удаление защиты AIP в ASProtect SKE v2.3
  8.     Исследуемая программа: UnPackMe_ASProtect.2.3.04.26.a.exe
  9.     Конфигурация: ODbgScript v1.3x или выше; запуск из OEP; пропуск
  10.     всех исключений
  11.     Дата: 5 августа 2006
  12. - = [Комментарий] = -
  13.     Благодарности: Рикардо Нарвахе и marciano (ибо я слегка
  14.     воспользовался его логикой для написания поискового движка)
  15. -=============================================================-
  16. */
  17. var oep
  18. var codebase
  19. var codesize
  20. var base_aspr
  21. var base_aip
  22. var ini_iat
  23. var dir
  24. var dir_iat
  25. var sig
  26. var dest
  27. var api
  28. var cont
  29. cmp $VERSION,"1.30" // Проверка версии OllyScript’а.
  30. jb err_version
  31. ask "Введите основание, на которое ссылаются эмулирующие CALL’ы ASProtect’а:"
  32. cmp $RESULT,0
  33. je salir
  34. mov base_aip,$RESULT    // Сохранение введенного адреса.
  35. mov oep,eip     // Сохранение значения OEP.
  36. gmi eip,codebase        // Определение начального адреса секции кода.
  37. mov codebase,$RESULT    // Сохранение полученного значения.
  38. gmi eip,codesize        // Определение размера секции кода.
  39. mov codesize,$RESULT    // Сохранение полученного значения.
  40. add codesize,codebase   // Сложение размера и нач. адреса.
  41. mov ini_iat,460814  // Сохранение адреса начала IAT.
  42. mov base_aspr,[46C048]  // В 46C048 сохранено основание секции, где определяется, к каким API-функциям должны направлять CALL’ы.
  43. add base_aspr,3B02E // К этому основанию добавляется константа для получения адреса, по которому видна API-функция.
  44. bphws base_aspr,"x" // Установка HBP на адрес, где видна API-функция.
  45. jmp buscar
  46. buscar:
  47. find codebase,#E8????????#  // Поиск CALL’ов в секции кода.
  48. cmp $RESULT,0   // Если ни одного CALL’а не найдено, процесс завершается.
  49. je no_calls
  50. mov dir,$RESULT // При обнаружении CALL’а его адрес сохраняется.
  51. mov sig,dir     // Копирование найденного адреса в другую переменную.
  52. mov dest,dir        // Копирование в еще одну переменную.
  53. add sig,5       // sig содержит адрес инструкции, следующей за CALL’ом.
  54. inc dest        // dest инкрементируется для получения опкодов после E8.
  55. mov dest,[dest]     // Извлекается offset, закодированный в CALL’е после опкода E8
  56. add dest,sig        // Теперь dest содержит адрес, к которому ведет CALL.
  57. cmp dest,base_aip   // Этот CALL есть в ASProtect’е?
  58. je ejecutar
  59. inc dir     // Если нет, обновляется указатель поиска.
  60. mov codebase,dir    // Указатель копируется и поиск повторяется.
  61. jmp buscar
  62. ejecutar:       // CALL ведет к Аспру.
  63. mov eip,dir     // В EIP копируется адрес найденного CALL’а, ведущего в Аспр,
  64. run         // и программа запускается.
  65. eob comprobar       // Если срабатывает BP, управление передается на метку 'comprobar'.
  66. comprobar:
  67. cmp eip,base_aspr   // BP находится в ожидаемой области?
  68. jne inesperado
  69. mov api,edx     // Если да, то из EDX сохраняется значение API-функции.
  70. jmp buscar_api      // Далее — поиск API-функции в IAT’е.
  71. buscar_api:
  72. cmp ini_iat, 460F28 // Начало и конец IAT’а равны?
  73. je error        // Если да, то API-функция в IAT’е не найдена.
  74. cmp [ini_iat],api       // Поиск API-функции по значению указателя.
  75. je reparar      // Если API-функция найдена, то ее надо восстановить.
  76. add ini_iat,4       // Если нет — увеличить указатель на 4 во избежание ошибок поиска.
  77. jmp buscar_api      // Продолжить поиск.
  78. reparar:
  79. mov dir_iat,ini_iat // Сохранение адреса IAT, где найдена API-функция.
  80. ref dir     // Поиск ссылок на этот адрес.
  81. cmp $RESULT,0   // Если ссылка есть, то нужно ассемблировать JMP.
  82. jne reparar_jump
  83. eval "Call dword[{dir_iat}]"    // В противном случае — CALL.
  84. asm dir,$RESULT
  85. inc cont        // Счетчик для учета кол-ва восстановленных CALL’ов.
  86. inc dir
  87. mov codebase,dir
  88. mov ini_iat,460814  // Обновление указателя, чтобы следующий поиск производился с начала IAT’а.
  89. jmp buscar
  90. reparar_jump:
  91. eval "Jmp dword[{dir_iat}]" // Ассемблирование JMP’а.
  92. asm dir,$RESULT
  93. inc cont
  94. inc dir
  95. mov codebase,dir
  96. mov ini_iat,460814  // Обновление указателя, чтобы следующий поиск производился с начала IAT’а.
  97. jmp buscar
  98. inesperado:
  99. msg "Произошла внезапная остановка. Продолжить?"
  100. cmp $RESULT,0
  101. je salir
  102. run
  103. error:
  104. eval "Ошибка. Следует вручную восстановить CALL по адресу: {dir}h"
  105. msg $RESULT
  106. run
  107. no_calls:
  108. bphwc base_aspr
  109. eval "Работа завершена. Восстановлено {cont}h CALL’ов ;)"
  110. msg $RESULT
  111. jmp salir
  112. err_version:
  113. msg "Ошибка. Требуется более новая версия OllyScript’а"
  114. ret
  115. salir:
  116. bphwc base_aspr
  117. mov eip,oep
  118. ret

Думаю, что комментарии, приведенные в самом скрипте, вполне достаточно описывают его работу. Обнаружение процедуры ASProtect’а, определяющей, какая API-функция должна использоваться, работает на любом компьютере, и при этом рекомендованные мной BPM’ы не задействованы.

Здесь происходит извлечение основания секции, созданной процедурой ASProtect’а:

Код (Text):
  1.  
  2. mov base_aspr,[46C048]  // В 46C048 сохранено основание секции, где определяется, к каким API-функциям должны направлять CALL’ы.
  3. add base_aspr,3B02E // К этому основанию добавляется константа для получения адреса, по которому видна API-функция.
  4. bphws base_aspr,"x" // Установка HBP на адрес, где видна API-функция.
  5. jmp buscar

По адресу программы 46C048 сохранена база той секции, где определяется API-функция. После извлечения база суммируется с константой, и так находится ключевое место на любом компьютере, потому что секции равны, а варьируется лишь начальный адрес. В данном случае ключевое место — 3B02E от начала, и после его вычисления на нем устанавливается HBP для остановок при выполнении.

Затем под меткой buscar происходит поиск всех CALL’ов от начала секции 401000 и определяется, какие из них ведут в область ASProtect’а по введенному нами значению.

Код (Text):
  1.  
  2. ejecutar:       // CALL ведет к Аспру.
  3. mov eip,dir     // В eip копируется адрес найденного CALL’а, ведущего в Аспр,
  4. run         // и программа запускается.
  5. eob comprobar       // Если срабатывает BP, управление передается на метку 'comprobar'.

Здесь предусмотрена проверка BP на случай, если кто-нибудь забыл удалить отработанный BP или Break-on-execute, что могло привести к исключениям и нарушению в работе скрипта:

Код (Text):
  1.  
  2. comprobar:
  3. cmp eip,base_aspr   // BP находится в ожидаемой области?
  4. jne inesperado
  5. mov api,edx     // Если да, то из EDX сохраняется значение API-функции.
  6. jmp buscar_api      // Далее — поиск API-функции в IAT’е.

Если это ожидаемая область (то есть место, показывающее API-функцию), то в IAT’е должен быть элемент, соответствующий найденной API-функции.

Код (Text):
  1.  
  2. buscar_api:
  3. cmp ini_iat, 460F28 // Начало и конец IAT’а равны?
  4. je error        // Если да, то API-функция в IAT’е не найдена.
  5. cmp [ini_iat],api       // Поиск API-функции по значению указателя.
  6. je reparar      // Если API-функция найдена, то ее надо восстановить.
  7. add ini_iat,4       // Если нет — увеличить указатель на 4 во избежание ошибок поиска.
  8. jmp buscar_api      // Продолжить поиск.

Здесь выполняется поиск соответствующего элемента во всей IAT, а после его нахождения происходит переход на метку reparar, где восстанавливаются CALL’ы или JMP’ы, направляющие в область ASProtect’а. Найденная API-функция верна и соответствует элементу IAT’а. Если требуется восстановить CALL, то он заменяется косвенным CALL’ом, берущим значение из упомянутого элемента IAT’а, а если JMP, то ассемблируется косвенный JMP и повторяется всё с начала. И так происходит до тех пор, пока ничего, требующего восстановления, обнаружено не будет, то есть всё уже исправлено.

Рассмотренный скрипт работает хорошо и написан довольно ясно. Помимо наличия комментариев, он также оформлен в виде блоков. Ведь так мало авторов утруждают себя подобными вещами, облегчающими анализ функционирования скриптов. Hiei, ты выиграл путевку в путешествие, хе-хе, но чтобы получить ее, тебе придется приехать сюда, ха-ха-ха. Большое спасибо за проделанный труд!

Следующий конкурс будет проще и состоять будет из двух частей (может быть на этот раз объявится большее число участников!) В первой части нужно написать скрипт к TPPpack для прибытия в OEP и восстановления украденных байтов, что сделать совсем не трудно. Рассматриваемый анпэкми приложен к статье, и, кроме того, есть туториал marciano к Конкурсу-97, где объясняется, как это выполнить вручную. Так что всё предельно просто. Однако использовать можно только плагины Hide Debugger 1.24, HideOD и OllyScript (лучше его последнюю версию ODbgScript) и ничего более — это требуется в целях унификации.

Во второй части нужно написать скрипт для восстановления IAT TPPpack. Оба скрипта самостоятельны и могут быть представлены в двух частях, либо вместе — кто как хочет.

Иными словами, задача такая:

  • 1-я часть: скрипт для поиска OEP и восстановления украденных байтов.
  • 2-я часть: скрипт для полного восстановления IAT’а.
Допускается использование только 3-х упомянутых плагинов (но не стоит спрашивать, нужно ли отключать CommandBar, хе-хе). Решения следует отправить до 30 августа. Напоминаю, что их можно прислать как по-отдельностьи, так и вместе.

Туториал marciano скоро появится на моем сайте здесь.

Спасибо за участие и до встречи в 53-ей главе!

Файлы к статье © Рикардо Нарваха, пер. Рома Стремилов


1 4.236
archive

archive
New Member

Регистрация:
27 фев 2017
Публикаций:
532

Комментарии


      1. virtuha 23 май 2017
        Оглавление
        Введение в крэкинг с нуля, используя OllyDbg - Глава 1
        Введение в крэкинг с нуля, используя OllyDbg - Глава 2
        Введение в крэкинг с нуля, используя OllyDbg - Глава 3
        Введение в крэкинг с нуля, используя OllyDbg - Глава 4
        Введение в крэкинг с нуля, используя OllyDbg - Глава 5
        Введение в крэкинг с нуля, используя OllyDbg - Глава 6
        Введение в крэкинг с нуля, используя OllyDbg - Глава 7
        Введение в крэкинг с нуля, используя OllyDbg - Глава 8
        Введение в крэкинг с нуля, используя OllyDbg - Глава 9
        Введение в крэкинг с нуля, используя OllyDbg - Глава 10
        Введение в крэкинг с нуля, используя OllyDbg - Глава 11
        Введение в крэкинг с нуля, используя OllyDbg - Глава 12
        Введение в крэкинг с нуля, используя OllyDbg - Глава 13
        Введение в крэкинг с нуля, используя OllyDbg - Глава 14
        Введение в крэкинг с нуля, используя OllyDbg - Глава 15
        Введение в крэкинг с нуля, используя OllyDbg - Глава 16
        Введение в крэкинг с нуля, используя OllyDbg - Глава 17
        Введение в крэкинг с нуля, используя OllyDbg - Глава 18
        Введение в крэкинг с нуля, используя OllyDbg - Глава 19
        Введение в крэкинг с нуля, используя OllyDbg - Глава 20
        Введение в крэкинг с нуля, используя OllyDbg - Глава 21
        Введение в крэкинг с нуля, используя OllyDbg - Глава 22
        Введение в крэкинг с нуля, используя OllyDbg - Глава 23
        Введение в крэкинг с нуля, используя OllyDbg - Глава 24
        Введение в крэкинг с нуля, используя OllyDbg - Глава 25
        Введение в крэкинг с нуля, используя OllyDbg - Глава 26
        Введение в крэкинг с нуля, используя OllyDbg - Глава 27
        Введение в крэкинг с нуля, используя OllyDbg - Глава 28
        Введение в крэкинг с нуля, используя OllyDbg - Глава 29
        Введение в крэкинг с нуля, используя OllyDbg - Глава 30
        Введение в крэкинг с нуля, используя OllyDbg - Глава 31
        Введение в крэкинг с нуля, используя OllyDbg - Глава 32
        Введение в крэкинг с нуля, используя OllyDbg - Глава 33
        Введение в крэкинг с нуля, используя OllyDbg - Глава 34
        Введение в крэкинг с нуля, используя OllyDbg - Глава 35
        Введение в крэкинг с нуля, используя OllyDbg - Глава 36
        Введение в крэкинг с нуля, используя OllyDbg - Глава 37
        Введение в крэкинг с нуля, используя OllyDbg - Глава 38
        Введение в крэкинг с нуля, используя OllyDbg - Глава 39
        Введение в крэкинг с нуля, используя OllyDbg - Глава 40
        Введение в крэкинг с нуля, используя OllyDbg - Глава 41
        Введение в крэкинг с нуля, используя OllyDbg - Глава 42
        Введение в крэкинг с нуля, используя OllyDbg - Глава 43
        Введение в крэкинг с нуля, используя OllyDbg - Глава 44
        Введение в крэкинг с нуля, используя OllyDbg - Глава 45
        Дополнение к 45-ой главе «Введения в крэкинг, используя OllyDbg»
        Введение в крэкинг с нуля, используя OllyDbg - Глава 46
        Введение в крэкинг с нуля, используя OllyDbg - Глава 47
        Введение в крэкинг с нуля, используя OllyDbg - Глава 48
        Введение в крэкинг с нуля, используя OllyDbg - Глава 49
        Введение в крэкинг с нуля, используя OllyDbg - Глава 50
        Введение в крэкинг с нуля, используя OllyDbg - Глава 51
        Введение в крэкинг с нуля, используя OllyDbg - Глава 52
        Введение в крэкинг с нуля, используя OllyDbg - Глава 53