> For the complete documentation index, see [llms.txt](https://backoftut.gitbook.io/intro-cracking-with-ollydbg-2/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://backoftut.gitbook.io/intro-cracking-with-ollydbg-2/ch-43.md).

# Глава 43

В предыдущей части мы сосредоточились на починке украденных байт, а сейчас нашей задачей является IAT. Снова открываем распакуй-меня [\[ссылка\]](https://github.com/yutewiyof/intro-cracking-with-ollydbg/tree/3679d233f4d394747f712e9b6b09bc9c2a3cad80/.gitbook/assets/files/42/UnPackMe_ACProtect1.09g.f.7z) в OllyDbg и доходим до фальшивой OEP с помощью скрипта.

![](https://416819976-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LjyqT34OedPJiOdIrDw%2F-LmvTfhKwMHzvDz9duQT%2F-LmvTvxEzvy3J7UoWrwQ%2F1.png?generation=1566513560107214\&alt=media)

Сейчас находимся в начале программы. Теперь, поскольку у нас есть скрипт \[\[ссылка]]\(.gitbook/assets/files/42/HBP%20(42).7z) для того, чтобы попасть в OEP, который остался нам с прошлой главы, устанавливаем две необходимые точки останова и используем их.

![](https://416819976-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LjyqT34OedPJiOdIrDw%2F-LmvTfhKwMHzvDz9duQT%2F-LmvTvxZ3q2BWYvMWwJ8%2F2.png?generation=1566513555086246\&alt=media)

![](https://416819976-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LjyqT34OedPJiOdIrDw%2F-LmvTfhKwMHzvDz9duQT%2F-LmvTvxlO5Cgzrs7dbni%2F3.png?generation=1566513555943442\&alt=media)

![](https://416819976-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LjyqT34OedPJiOdIrDw%2F-LmvTfhKwMHzvDz9duQT%2F-LmvTvxyoU6r4s8d9IOo%2F4.png?generation=1566513553194542\&alt=media)

И сейчас находимся на OEP. Ниже рассмотрим, как улучшить скрипт, чтобы автоматически устанавливать две точки останова, и чтобы запрашивался адрес HBP. Пока редактировать не будем, послужит нам как есть.

![](https://416819976-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LjyqT34OedPJiOdIrDw%2F-LmvTfhKwMHzvDz9duQT%2F-LmvTvyFXRQUAYCV-qWi%2F5.png?generation=1566513555436583\&alt=media)

Ищем вызов API-функции, для чего можем использовать SEARCH FOR INTERMODULARS CALLS.

![](https://416819976-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LjyqT34OedPJiOdIrDw%2F-LmvTfhKwMHzvDz9duQT%2F-LmvTvycL3ZxTQvlKNpO%2F6.png?generation=1566513555632922\&alt=media)

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

![](https://416819976-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LjyqT34OedPJiOdIrDw%2F-LmvTfhKwMHzvDz9duQT%2F-LmvTvyo0wrqD2P6SKB1%2F7.png?generation=1566513555534538\&alt=media)

Здесь видим вызов, который берёт значение 460e80, что является элементом IAT. Смотрим IAT в дампе.

Видим ворох элементов, которые, в данном случае, являются переадресовочными не в секцию, созданную упаковщиком. Может в ту же секцию, где исполняется сам упаковщик? Смотрим карту памяти.

![](https://416819976-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LjyqT34OedPJiOdIrDw%2F-LmvTfhKwMHzvDz9duQT%2F-LmvTvz-ewTkgWQtZXAV%2F8.png?generation=1566513554752336\&alt=media)

![](https://416819976-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LjyqT34OedPJiOdIrDw%2F-LmvTfhKwMHzvDz9duQT%2F-LmvTvzB_LJ-PkhciawT%2F9.png?generation=1566513556413251\&alt=media)

Вот эта секция. Если спустимся ниже и посмотрим образ точки входа, где запускается упаковщик, то вспомним, что это был адрес 46b000, поэтому упаковщик не заморачивался сильно с созданием новой секции, чтобы скрыть в ней API-функции.

Вопрос заключается в том, что раз мы знаем, что это переадресовочные элементы, может нам повезёт, и мы найдём волшебный переход или другой способ починить IAT?

![](https://416819976-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LjyqT34OedPJiOdIrDw%2F-LmvTfhKwMHzvDz9duQT%2F-LmvTvzP0SW12IDkmau4%2F10.png?generation=1566513555834502\&alt=media)

Используем указанный переход 460aDC, чтобы попытаться найти волшебный переход. Чтобы не пришлось менять скрипт из OEP, скопируем его в другую папку, переименуем его в OEP и скопируем обратно.

![](https://416819976-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LjyqT34OedPJiOdIrDw%2F-LmvTfhKwMHzvDz9duQT%2F-LmvTvzdnbhv5R-EdC0N%2F11.png?generation=1566513557286540\&alt=media)

Таким образом, мы сохранили под именем "OEP" скрипт, который используем для нахождения OEP, а теперь можем модифицировать HBP, чтобы найти волшебный переход.

Здесь меняем HBP на плохие элементы, а затем меняем тип на W, то есть на запись или WRITE.

Теперь стираем HBP, установленные ранее, и делаем перезапуск.

![](https://416819976-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LjyqT34OedPJiOdIrDw%2F-LmvTfhKwMHzvDz9duQT%2F-LmvTvzqD9nGZ59gnE5x%2F12.png?generation=1566513558362058\&alt=media)

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

![](https://416819976-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LjyqT34OedPJiOdIrDw%2F-LmvTfhKwMHzvDz9duQT%2F-LmvTw-1fg9H7_cK5ilQ%2F13.png?generation=1566513554888397\&alt=media)

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

![](https://416819976-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LjyqT34OedPJiOdIrDw%2F-LmvTfhKwMHzvDz9duQT%2F-LmvTw-B9-dRXJoCLaBC%2F14.png?generation=1566513555679202\&alt=media)

Вот эта инструкция, сохраняющая плохое значение, и видим, что EAX содержит значение, которое будет сохранено.

Проверим, происходит ли запись в переадресовочную зону, для чего нам не нужно идти до OEP, смотрим 46b492:

![](https://416819976-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LjyqT34OedPJiOdIrDw%2F-LmvTfhKwMHzvDz9duQT%2F-LmvTw-KjByMrSw7Ay2a%2F15.png?generation=1566513558602014\&alt=media)

![](https://416819976-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LjyqT34OedPJiOdIrDw%2F-LmvTfhKwMHzvDz9duQT%2F-LmvTw-UVh4EZp8AWqxl%2F16.png?generation=1566513553183227\&alt=media)

Видим, что переадресация довольно дурацкая – здесь помещается в стек 5bf11a9, а затем это значение XOR'ится с 793e0502. Результат этой операции становится первым значением стека, и когда доходит до выполнения RET'а, возврат произойдёт по этому адресу.

Смотрим, может ли посчитать адрес API-функции, куда, в итоге, произойдёт переход.

5bf11a9 XOR 793e0502 = 7C8114AB

Это адрес API-функции, куда ведёт переадресация. Возвращаемся обратно в OllyDbg, и смотрим, найдём ли мы здесь что-нибудь.

![](https://416819976-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LjyqT34OedPJiOdIrDw%2F-LmvTfhKwMHzvDz9duQT%2F-LmvTw-c8sA3PlBfXhoS%2F17.png?generation=1566513557916803\&alt=media)

Если поднимемся чуть выше по стеку, то увидим там правильный адрес API-функции. Теперь нам нужно узнать, работает ли это для все переадресовочных элементов, так что останавливаем скрипт.

![](https://416819976-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LjyqT34OedPJiOdIrDw%2F-LmvTfhKwMHzvDz9duQT%2F-LmvTw-lyQSvR0LfnHe2%2F18.png?generation=1566513555029962\&alt=media)

И смотрим, что произойдёт, если установим BPM ON WRITE на плохие элементы, которые ещё не заполнены из таблицы.

![](https://416819976-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LjyqT34OedPJiOdIrDw%2F-LmvTfhKwMHzvDz9duQT%2F-LmvTw-vU4ZXvwxEax8v%2F19.png?generation=1566513555282858\&alt=media)

Делаем RUN и останавливаемся, чтобы остановиться на следующем элементе.

![](https://416819976-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LjyqT34OedPJiOdIrDw%2F-LmvTfhKwMHzvDz9duQT%2F-LmvTw062dEHLynhkfsF%2F20.png?generation=1566513551219002\&alt=media)

И видим, что это API-функция MulDiv. Если нас не затруднит пойти в переадресовочную область и сделать XOR, что ведёт сюда, так что мы видим возможность починки. Хорошая API-функция расположена в стеке, а точнее в \[ebp-0c].

![](https://416819976-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LjyqT34OedPJiOdIrDw%2F-LmvTfhKwMHzvDz9duQT%2F-LmvTw0I87JvMvOuyQyH%2F21.png?generation=1566513555341300\&alt=media)

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

![](https://416819976-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LjyqT34OedPJiOdIrDw%2F-LmvTfhKwMHzvDz9duQT%2F-LmvTw0Vy0PBJxFkUA9P%2F22.png?generation=1566513553321130\&alt=media)

Так что устанавливаем BPM ON WRITE на него.

![](https://416819976-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LjyqT34OedPJiOdIrDw%2F-LmvTfhKwMHzvDz9duQT%2F-LmvTw0fiIvP9T_D7gok%2F23.png?generation=1566513554528340\&alt=media)

Делаем RUN и останавливаемся здесь.

![](https://416819976-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LjyqT34OedPJiOdIrDw%2F-LmvTfhKwMHzvDz9duQT%2F-LmvTw0rvj2ToktZfhMs%2F24.png?generation=1566513555421625\&alt=media)

Видим, что это тот же адрес, где сохраняются плохие элементы. Также в случае хороших элементов смотрим \[ebp-0c], где находится правильный адрес.

![](https://416819976-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LjyqT34OedPJiOdIrDw%2F-LmvTfhKwMHzvDz9duQT%2F-LmvTw101wfVeQJ2COJJ%2F25.png?generation=1566513554238420\&alt=media)

Видим, что в случае с хорошими API-функциями правильного адреса здесь не сохраняется, что очень жалко, так как иначе было бы очень легко сделать скрипт, который был смотрел значение \[esp-0c], но решить эту проблему также легко.

Ничего сложного, сделаем скрипт, используя тот же HBP.

Что мы сделаем? Установим HBP ON EXECUTION на то место, где сохраняются значения IAT, и когда скрипт определит, что остановились здесь, проверим, содержит ли EAX хорошее значение или плохое. В последнем случае сохраним значение \[esp+0c] в \[EDI], которое указывает на заполняемый элемент таблицы.

Смотрим скрипт.

```
var aux
var aux2

inicio:

bphws 4743d5, "x"

trabajo:

eob pirulo
run

pirulo:
log eip
cmp eip, 7c91eaec
je quitar
cmp eip, 7c91eb03
je restaurar
cmp eip, aux
je restaurar2
cmp eip, 4743d5
je reparar
jmp final

quitar:
bphwc 4743d5
jmp trabajo

restaurar:
mov aux, esp
mov aux, [aux]
add aux, 0b8
mov aux, [aux]
log aux
bp aux
jmp inicio

restaurar2:
bc aux
jmp inicio

reparar:
cmp eax, 500000
ja inicio
mov aux2, esp
sub aux2, 0c
mov aux2, [aux2]
log aux2
mov [edi], aux2
jmp inicio

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

Вот скрипт. Первое, что нужно пояснить – устанавливаем HBP ON EXECUTION на следующую инструкцию, то есть на 4743d5. Раз HBP ON EXECUTION, то остановка будет происходит точно в тот момент, когда происходит выполнение, чего не было бы с HBP ON WRITE или ON ACCESS.

Скрипт прост и основывается на том, что мы делали раньше, только устанавливаем HBP ON EXECUTION на 4743d5 – следующей строке после сохранения плохого значения.

```
cmp eip, 4743d5
je reparar
```

В части pirulo, где скрипт получает контроль по нахождению исключения, добавляем к ней сравнение EIP с 4743d5, чтобы узнать, действительно ли находимся в желаемом месте, и оттуда прыгаем к reparar, где и творится магия.

```
reparar:
cmp eax, 500000
ja inicio
mov aux2, esp
sub aux2, 0c
mov aux2, [aux2]
log aux2
mov [edi], aux2
jmp inicio
```

В reparar мы делаем следующее: проверяем, содержит EAX хорошее значение или плохое, и как видим, все переадресовочные значения ведут в секцию упаковщика. Его адрес меньше 500000, поэтому если видим, что EAX больше 500000, то потому что это хорошая API-функция. В этом случае мы ничего не чиним и возвращаемся в начало. В противном случае у нас плохое значение, и используем переменную aux2, чтобы найти значение ESP, от которого отнимаем 0c, а затем находим его содержимое. Его записываем в лог, а затем сохраняем в \[EDI], который указывает на элемент, откуда загружается плохое значение на предыдущей строке программы. Вот мы и разобрались с этим, затем возвращаемся и пробуем скрипт.

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

![](https://416819976-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LjyqT34OedPJiOdIrDw%2F-LmvTfhKwMHzvDz9duQT%2F-LmvTw1SQPBR5MiA7WbS%2F26.png?generation=1566513554344834\&alt=media)

Запускается программа, смотрим, что осталось в IAT.

![](https://416819976-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LjyqT34OedPJiOdIrDw%2F-LmvTfhKwMHzvDz9duQT%2F-LmvTw1adNGVOeSRSg3O%2F27.png?generation=1566513555391308\&alt=media)

Красота, хе-хе. С помощью запущенной программы с починенным IAT можем починить дамп. Уже видели, что нет необходимости останавливаться на OEP, чтобы использовать процесс в IMP REC’е, когда есть правильная таблица, так что без проблем починим дамп.

Переименовываем скрипт в IAT, и снова пробуем скрипты, теперь, когда они все разделены.

![](https://416819976-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LjyqT34OedPJiOdIrDw%2F-LmvTfhKwMHzvDz9duQT%2F-LmvTw1qfC_SfwaICj1X%2F28.png?generation=1566513558695341\&alt=media)

Единственное, что осталось, связанное с IAT – это найти начало и размер таблицы, которые необходимо указать в IMP REC’е.

![](https://416819976-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LjyqT34OedPJiOdIrDw%2F-LmvTfhKwMHzvDz9duQT%2F-LmvTw2AKXn8rS013VES%2F29.png?generation=1566513554843321\&alt=media)

Поднимаясь по IAT, ясно видим, что IAT начинается в 460818, конец в 460f28, и его также несложно найти:

![](https://416819976-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LjyqT34OedPJiOdIrDw%2F-LmvTfhKwMHzvDz9duQT%2F-LmvTw2Osbyr6qyyyvuU%2F30.png?generation=1566513556457493\&alt=media)

OEP = **271b5**

НАЧАЛО = **60818**

РАЗМЕР = 460f28 - 460818 = **710**

Можем использовать фальшивый OEP, нет проблем – потом это можно исправить вручную.

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

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