# Глава 40

После того, как мы продолжили разбираться с таблицей IAT pelock’а [\[ссылка\]](https://github.com/yutewiyof/intro-cracking-with-ollydbg/blob/master/.gitbook/assets/files/39/UnPackMe_PELock1.06.d.7z), а также антидамповыми приёмами, в этой части будет рассмотрено две темы: одна, которая была пропущена ранее, и другая, которая очень поможет в работе с tpelock’ом или другой похожей программой, которая снимает или обнаруживает установленные HBP.

Первая тема была затронута в главе 39, но мы не уделили ей никакого внимания. Если вы скачивали файл, прилагаемый к предыдущей главе, то там был файл leer.txt, в котором было сказано:

_Для того, чтобы решить данный туториал, нужно использовать пропатченный ollydbg (в архиве Parcheado 4.rar_ [_\[ссылка\]_](https://github.com/yutewiyof/intro-cracking-with-ollydbg/blob/master/.gitbook/assets/files/40/Parcheado%204.7z)_). Необходимо разместить его в той же папке, что и Ollydbg.exe, так как у обычного Ollydbg есть баг обработки неправильных инструкций, которые выбрасывают окошко с выбором "да или да" для установки галочки на debugging options-exceptions для выхода. "Parcheado 4" чинит этот баг. На тот момент, когда я писал главу, я забыл об этом, но Solid мне напомнил, что нельзя решить туториал из-за этой проблемы, так что используйте фикс, и не будет никакой проблемы._

_Рикардо Нарваха_

Пробуем пропатченный Ollydbg под названием "Parcheado 4", который находится в той же папке, что и Ollydbg.exe, и используем для решения туториал по PELOCK’у.

Что я хотел объяснить, так это главную вещь, которая делает этот "parcheado 4" особенным.

Хорошо, в Ollydbg есть баг обработки исключений типа "ILLEGAL INSTRUCTION". Если в обычном Ollydbg с плагинами для его сокрытия отметим все галочки в DEBUGGING OPTIONS-EXCEPTIONS и нажмём RUN:

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-d001714a9b434af026ec7eeb198bd11deffeb535%2F1.png?alt=media)

Получаем данную ошибку, в то время как в "parcheado 4" выполняется превосходно. Нажимаем на "Aceptar" и смотрим, что случилось в логе Ollydbg.exe.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-69f011591209477636a3313bebdcb610e26f0be7%2F2.png?alt=media)

Видим, что последнее исключение, до которого появляется окошко – это ILLEGAL INSTRUCTION. Сейчас посмотрим debugging options-exceptions, и уберём галочку с данного типа исключений.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-92d0d1a150091c42949104e36a6164d0b296e433%2F3.png?alt=media)

Это и есть галочка, отвечающая за данное исключение, снимаем её, запускаем pelock и делаем RUN.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-7c8bcd5ef22325412f85d0fc9ac8f3abd36cbce4%2F4.png?alt=media)

Останавливаемся на исключении, и если пройдём его с помощью SHIFT+F9, то не будет никакой проблемы и pelock запустится.

Это значит, что у Ollydbg проблема с прохождением данного исключения в автоматическом режиме.

Если просто нажать SHIFT+F9, то всё будет в порядке, но этот баг может стать проблемой, так как многие программисты генерируют 200 или 300 таких исключений, и их прохождение в ручном режиме по меньшей мере трудновыносимо.

Теперь возвращаемся, чтобы установить галочку и снова получаем сообщением об ошибке.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-77240ea42c42f1eaf46f6244a3219206df5214bf%2F5.png?alt=media)

Как самые модные крэкеры, мы может попытаться крэкнуть сам Ollydbg, чтобы починить баг, для чего откроем второй пустой Ollydbg, с помощью которого и крэкнем остановку на сообщении с ошибкой.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-bed8084030e364b4b5351331668e64296f7c3000%2F6.png?alt=media)

В этом пустом Ollydbg выполним FILE-ATTACH, чтобы прикрепить и отладить другой Ollydbg, который остановлен на сообщении с ошибкой.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-655da0f18a531233ff9a767f39974822ae77eafc%2F7.png?alt=media)

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-539791a943f5b9ba52145126ba8ec5d23d324628%2F8.png?alt=media)

В открывшемся окне ищем процесс Ollydbg, чьё окно имеет название "Error", и прикрепляем его.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-194c8b4e0607594d77e63eebd94aea6b68216bdf%2F9.png?alt=media)

Останавливаемся здесь, делаем RUN.

Теперь смотрим карту памяти.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-5e8db32e3c629d4333f870e0e775ceaa46cbdbf0%2F10.png?alt=media)

Конечно, жертвой является другой Ollydbg, чьи секции мы здесь и наблюдаем. Установим Bp MessageBoxA.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-8d1752abeedbbff972d7ca0ad81182587d64c9d0%2F11.png?alt=media)

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-fb5b448db0c53540fbfc8d9ae755364c93afdbe3%2F12.png?alt=media)

Установив BP на RET API-функции MessageBoxA и нажав на кнопку в окошке с сообщением, остановимся на RET при возврате из этого окошка.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-d001714a9b434af026ec7eeb198bd11deffeb535%2F1.png?alt=media)

Здесь видим место в программе, куда возвратились из API-функции. Нажимаем F7.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-4bcd53797e30c12516fe714f199793ffae3c5a79%2F13.png?alt=media)

Если помните, таков был текст сообщения.

Поищем среди строк в OllyDbg.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-6ff81e1fdf0d4669dbb9c0a19fef51b74b66a5ec%2F14.png?alt=media)

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-a73f87761e0f3937a65ccef5c28131e21bb3b747%2F15.png?alt=media)

И здесь ищем слово "bypass", которое есть в сообщении.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-2fc029ec38349803fdf26fe2b3882b6fee18e27c%2F16.png?alt=media)

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

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-be89ca049f3fa5e6c150fa173d17ae8f1f294960%2F17.png?alt=media)

Видим, что один из этих JNZ можно заменить на JMP и вот наша программа пропатчена, сохраняем наши изменения с помощью COPY TO EXECUTABLE и SAVE FILE.

Откроем "parcheado 4" в OllyDbg и посмотрим эту область кода:

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-29b7f3039decd648ce2e68045274837551684891%2F18.png?alt=media)

Видим, что переходы пропатчены таким образом, чтобы перепрыгнуть через окошко, всё, что нужно сделать – это изменить последний перед выводом окошка условный переход на JMP 43528D, а если переход случиться в другом месте, то окошко будет обойдено естественным путём.

Ок, вот и весь секрет "parcheado 4", поэтому в нём нет бага с ILLEGAL INSTRUCTION как в обычном Ollydbg.exe, так что можете его пропатчить сами или использовать тот, что шёл с 39 главой.

Вторая часть этого туториала заключается в создании простого скрипта, для чего мы будем использовать OLLYSCRIPT 0.92 [\[ссылка\]](https://github.com/yutewiyof/intro-cracking-with-ollydbg/blob/master/.gitbook/assets/files/40/OllyScripts092.7z), который можно найти в файлах к этой главе. Положим DLL плагина в соответствующую папку.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-984b1e89d56c678ae94e68fce61c3b22ffb0a430%2F19.png?alt=media)

Теперь открываем "parcheado 4".

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-e393fb9aadeeca4b15632e13d5563796da4187aa%2F20.png?alt=media)

Видим, что наш плагин появился в соответствующем подменю.

Теперь открываем pelock, изучаемый нами. Идея в том, чтобы сделать минискрипт, который обеспечит работу HBP и не будет определяться упаковщиком.

Это будет простой скрипт. Команды можно посмотреть в README к плагину OLLYSCRIPT.

Идея следующая. Как видели в предыдущей части, каждый раз, когда останавливаемся на KiUserExceptionDispatcher, то находимся прямо перед тем местом, где операционная система доходит до обработчика исключений и где, как мы знаем, могут быть обнаружены и стёрты HBP, так что нам нужен скрипт, который каждый раз, когда программа останавливается на Bp KiUserExceptionDispatcher, стирал бы HBP, а при вызове ZwContinue восстанавливала бы его обратно.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-4ab3340561507f803b56f59f63d63c54bdd7df08%2F21.png?alt=media)

Так как это наш первый скрипт, то не будем его усложнять. BP по адресам KiUserExceptionDispatcher и вызова, ведущего к ZwContinue, устанавим вручную, так как мы уже знаем, где они находятся. Это можно сделать без особых проблем и скриптом, но незачем слишком усложнять, так что идея заключается в том, чтобы установить BP по адресам KiUserExceptionDispatcher и вызова, ведущего к ZwContinue, вручную согласно картинке.

Теперь, установив вручную BP, начинаем скрипт, который обычно начивается с

`inicio:`

Это метка необходима, если потребуется перейти в начало скрипта, что делается с помощью команды Jmp inicio. После inicio идёт HBP, который нужно установить. Например:

`bphws 12ffc4, "r"`

bphws – это команда, которая устанавливает аппаратную точку останова по указанному адресу, в данном случае это 12ffc4, а r в кавычках означает "на доступ" или "на чтение", что одно и то же. Также есть "w" – "на запись" и "x" – "на выполнение".

```
inicio:
bphws 12ffc4, "r"
trabajo:
```

После установки одной или нескольких аппаратных точек останова идёт ещё одна метка, чтобы можно было вернуться в место непосредственно после установки HBP.

```
inicio:
bphws 12ffc4, "r"
trabajo:
eob pirulo
run
```

Здесь видим команду eob, которая делает то же, что происходит, когда OllyDbg обнаруживает исключение или точку останова – передаёт управление по метке, в данном случае "pirulo". Это означает, что когда программа остановится на исключении или точке останова, то скрипт продолжит своё выполнение с метки pirulo. Дальше делаем RUN с помощью команды run.

Это главная часть, где OllyDbg начинает выполнять жертву. Нам нужно подготовиться к тому, что делать, когда будет обнаружено исключение или точка останова, для чего распишем метку pirulo:

```
pirulo:
cmp eip, 7c91eaec
je quitar
cmp eip, 7c91eb03
je restaurar
jmp final
```

На моей машине 7c91eaec – это адрес KiUserExceptionDispatcher, то есть когда происходит остановка на этом BP, eip моей машины будет содержать 7c91eaec, так что это инструкция гарантирует, что если мы действительно здесь, то происходит переход по метке quitar, чтобы стереть HBP.

Затем идёт другое сравнение на то, когда происходит остановка на другом BP, находящемся на CONTINUE. Когда обнаруживается, что программа остановилась на данном BP, то переходим на метку restaurar, чтобы заново установить HBP.

Дальше остаётся немного:

```
quitar:
bphwc 12ffc4
jmp trabajo
```

Когда переходим на quitar, чтобы стереть HBP, то для этого используем команду bphwc, а затем переходим на метку trabajo, чтобы продолжить выполнение программы, но уже без HBP.

Другая метка служит для восстановления HBP при вызове ZwContinue.

```
restaurar:
jmp inicio
```

Которая напрямую переходит на начало, где снова устанавливается HBP, а цикл начинается заново.

Конечно, нужно учитывать возможность остановки программы, когда OllyDbg останавливается на нашем HBP, в данном случае это последняя часть.

Как запускается eob, когда случается точка останова или исключение, так при остановке на нашем HBP будет совершён переход на pirulo, и так как нет никакого BP, который бы мы установили вручную, то управление передаётся по метке final:

```
pirulo:
cmp eip, 7c91eaec
je quitar
cmp eip, 7c91eb03
je restaurar
jmp final
```

Вот что там:

```
final:
MSGYN "Continuar?"
cmp $RESULT,1
je inicio
ret
```

MSGYN заставляет появиться окошко с опцией "continuar" (продолжить). Смотрим, подходит ли нам место, где мы остановились, или хотим продолжить выполнение до следующего раза. Если нажимаем "YES", то в переменную $RESULT будет помещено значение 1, а если нажмём "NO", то 0, поэтому когда хотим продолжить, то по нажатию на "YES" скрипт проверяет, равен ли $RESULT одному, и передаёт управление на начало скрипта, а если "NO", то следующей идёт инструкция ret, где выполнение скрипта завершается, и OllyDbg останавливается там, где мы хотим.

Вот полный исходный текст скрипта (не забудьте поставить вручную BP на KiUserExceptionDispatcher и CALL’е, ведущего к ZwContinue).

```
inicio:
bphws 12ffc4, "r"
trabajo:
eob pirulo
run

pirulo:
cmp eip, 7c91eaec
je quitar
cmp eip, 7c91eb03
je restaurar
jmp final

quitar:
bphwc 12ffc4
jmp trabajo

restaurar:
jmp inicio

final:
MSGYN "Continuar?"
cmp $RESULT,1
je inicio
ret
```

Внизу изображена большая часть скрипта с поясняющими стрелочками, в inicio устанавливаем HB, и запускаем программу. Когда встретится BP или исключение, будет совершён переход на метку pirulo.

Переход на pirulo совершается только тогда, когда есть BP или исключение, и в этом момент нужно проверить различные возможности: является ли этот BP одним из установленных нами вручную, или это аппаратное исключение, или же какое-то другое исключение. Проверяем EIP. Можем определить, откуда произошёл переход на метку. Если это случилось из BP в KiUserExceptionDispatcher, то снимаем HBP, чтобы он не был определён обработчиком исключений, и продолжаем выполнение программы, но уже без HE.

Когда срабатывает BP, установленный на ZwContinue, снова прыгаем на метку pirulo, сравниваем EIP, и нам нужно перейти на restaurar, так как в этот момент обработчик исключений уже пройден, и можем снова установить точку останова. В случае, если сработал другой BP или остановились на HE, то переходим на final, где можем решить, хотим ли остановиться или продолжить. Если останавливаемся, то выполняется инструкция ret, если продолжаем, то совершается переход на inicio.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-632b27de4113063fc60f43df0b7ddfd139167276%2F22.png?alt=media)

Попробуем скрипт в действии. Сохраняем его в текстовый файл и запускаем pelock, после чего устанавливаем вручную 2 BP и идём в меню плагина.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-2898e8393c64802b7b86b9fc125befad216e3269%2F23.png?alt=media)

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-e6b2503a52dbf9164909387baad8a98d9fdad769%2F24.png?alt=media)

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-6da1985a614e616cdbed02e86bf05bbb3ffce307%2F25.png?alt=media)

Видим, что остановились на HBP. Чтобы продолжить, нажимаем YES.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-e93d759622c7c8f3d938419ad1df62288ab774ce%2F26.png?alt=media)

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-587dce99fc291b7a7f361641b9975d1a15c75648%2F27.png?alt=media)

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-41134791d5373f6c2d4a969739d606064aecadc9%2F28.png?alt=media)

Видим, что программа прекрасно выполнилась и в окошке аппаратных точек останова видим:

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-5a580f0c1a6c39057b0dcbef95e0e9358fa219ba%2F29.png?alt=media)

То же самое при установке, поэтому программа выполняется с HBP и останавливается на них без каких-либо проблем, чего мы и хотели добиться.

В главе 41 мы продолжим делать скрипты и починим pelock полностью.

\[C] Рикардо Нарваха, пер. Aquila
