> For the complete documentation index, see [llms.txt](https://yutewiyof.gitbook.io/intro-rev-ida-pro/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://yutewiyof.gitbook.io/intro-rev-ida-pro/chast-15.md).

# Часть 15

[\[Используемые материалы\]](https://github.com/yutewiyof/intro-rev-ida-pro/tree/e1367e11cc661f3d69c02ae5f733b7dd168bc5ab/.gitbook/assets/files/15.zip)

В предыдущей части, мы увидели несколько из многих методов, которые существуют для обнаружения и получения **OEP** в упакованном файле. Сейчас, вернёмся к двум пропущенными шагам: это **ДАМП** и **ВОССТАНОВЛЕНИЕ IAT**, стараясь объяснить их в этой главе.

![](/files/-LjpguuSPrve426wz5BW)

Мы снова попадаем в **OEP** программы и делаем её **ПОВТОРНЫЙ АНАЛИЗ**. Теперь у нас уже есть всё, чтобы сделать **ДАМП**.

Сейчас будем использовать **IDC** скрипт, а не **PYTHON**.

```cpp
Static main()
{
    auto fp, ea;
    fp = fopen("pepe.bin","wb");
    for(ea = 0x400000; ea < 0x40B200; ea++)
        fputc(Byte(ea), fp);
}
```

В скрипте введём **IMAGEBASE(БАЗА\_ОБРАЗА)**, адрес, которой равен **0x400000** и наибольший адрес последней секции исполняемого файла, который мы видим в **IDA** на вкладке **SEGMENTS**, который нужно **СДАМПИТЬ**. В этом случае секция **OVERLAY**, которая является последней секцией исполняемого файла, заканчивается по адресу **0x40B200**.

![](/files/-LjttuAkmCtfV1EKbITa)

![](/files/-LjttuAwc19Jh_0AnEGN)

Сохраним этот скрипт под каким-нибудь именем, например **DUMPER.IDC**

![](/files/-LjpguunYwXOJ7NkYnzl)

И запускаем его через **FILE → SCRIPT FILE**. Можно видеть, что **IDA** принимает скрипты как **PYTHON** так и свои родные **IDC**, поэтому тут с этим нет проблем.

![](/files/-LjpguurU98rzholNsFP)

Я делаю копию созданного файла и переименовываю его расширение в **EXE**. (Если Вы не видите расширения файлов, Вы должны изменить соответствующую опцию в **НАСТРОЙКАХ ПРОВОДНИКА**)

![](/files/-LjpguutENNyW7DP_yLS)

![](/files/-Ljpguuv44yt_VkGbS6P)

Видим, что у файла нет иконки, потому что некоторые шаги пропущены.

Во вложении приложен **PE EDITOR 1.7**, распакуем и запустим его.

![](/files/-LjpguuxP6oprBhi08nc)

Теперь идём в **СЕКЦИИ**.

![](/files/-Ljpguv2yuxK7zGRwq3x)

Здесь делаем правый щелчок в каждой из секций и выбираем пункт **DUMPFIXER**.

![](/files/-Ljpguv4R6Jk3cD7yaJ1)

![](/files/-Ljpguv63Oh_CYvULfTV)

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

**ЧТО ТАКОЕ IAT?**

**IAT** или **IMPORT ADDRESS TABLE** - это таблица, находящаяся в исполняемом файле, она используется, когда запускается программа. В ней программа сохраняет адреса импортируемых функций, которые она использует, для того, чтобы программа смогла запуститься на любом компьютере.

Если **IAT** верная и если мы дадим исполняемый файл другому человеку, **IAT** будет заполнена значениями, соответствующими конкретному компьютеру, независимо от версии **WINDOWS**, который он имеет, и будет оставаться совместимым, и хорошо работать.

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

Мы помним из предыдущей части, что я хотел объяснить различие между верхним изображением, которое принадлежит упакованному файлу, когда он был в **OEP** перед **ДАМПОМ** и исходного файла.

![](/files/-Ljpguv8uJ6dRCqVTKHG)

Оба изображения показывают адрес **0x403238** и похоже, что они имеют одинаковое содержимое. Сейчас, давайте откроем оригинальный файл.

![](/files/-LjttuCUaR_3N6x6MY41)

Здесь можно видеть **ФАЙЛОВОЕ СМЕЩЕНИЕ**, которое равно **0x1038**, чтобы иметь возможность искать данные в **HXD** в исходном исполняемом файле.

Давайте откроем с помощью **HXD** оригинальный файл.

![](/files/-LjttuCe2k0ah2-H3ipN)

Видим, что содержимое памяти по смещению **0x1038** равно **0x355E**.

Если я прибавлю значение **0x355E** к **IMAGEBASE**, которое равно **0x400000**, то получу результат **0x40355E**. Что существует по этому адресу?

Чтобы увидеть что там находиться, нужно загрузить исходный файл с помощью опции **MANUAL LOAD**, для того, чтобы **IDA** загрузила все секции исполняемого файла.

![](/files/-LjttuCmaQv9L5MvIVN2)

Соглашаемся со всеми секциями для загрузки и когда файл загрузится, идём по адресу **0x40355E** и видим в правой стороне имя **API** функции, оно равно **GetModuleHandleA**.

![](/files/-LjpguvGVbOIhubv9eer)

Итак, когда система загружает файл, программа начинает работать со всеми этими блоками. (**1** блок — это одна **API** функция. Прим. Яши) Их можно увидеть ниже на изображении.

![](/files/-LjttuCzu5xS4TACcPsl)

И каждый блок складывается с содержимым **IMAGEBASE** и ищет соответствующую функции строку. И из этой строки рассчитывается во время выполнения адрес для нашего компьютера. Как например в нашем случае ищется адрес **API** функции **GetModuleHandleA** на нашем компьютере и изменяется значение **5E 35** на адреса **API**.

Вот почему исполняемый файл работает на любом компьютере, потому что он всегда будет находить в каждой записи **IAT** имя соответcтвующей **API** функции и рассчитывать её адрес при загрузке программы. Таким образом всегда содержащийся в нём адрес будет действительным, хотя и будет отличаться от компьютера к компьютеру. Однако адрес блока **GetModuleHandleA** на всех компьютерах будет одинаковым во всех исполняемых файлах без рандомизации. Изменится только его содержимое.

Вот почему на любом компьютере, если я сделаю:

**CALL \[0x403238]**

Это всегда будет работать, потому что адрес **0x403238** - это запись **IAT** для функции **GetModuleHandleA**. Что будет меняться - это содержимое, которое система будет сохранять, изменив исходное значение **5E 35**, которое указывает на строку, если мы сложим её с базой.

Не закрывая две других **IDA** с упакованным файлом, который остановлен в **OEP** и исходным файлом, в третьей **IDA** я открываю **ДАМП**, который мы только что сделали. Это файл **PEPE** - **COPY.EXE**.

В этом файле идём в **IAT** по адресу **0x403238**.

![](/files/-LjttuDKzz58Dt6DoTwF)

Видим, что здесь смещение файла равно **0x3238** и оно не соответствует исходному файлу, потому что **DUMPFIXER** который исправлял **RAWSIZE** и **VIRTUALSIZE**, также изменил смещения, и запись **IAT API GMHA(**&#x47;MHA = GetModuleHandleA прим. Яш&#x438;**)**.

Если откроем этот файл в **HXD** и перейдём по адресу **0x3238**.

![](/files/-LjpguvMVNupJUr9-Ssd)

То по этому адресу увидим:

![](/files/-LjttuDcG9X1bcPPwxxn)

Видим, что здесь у нас есть адрес **API** функции, а не смещение, которое нужно сложить с **IMAGEBASE**, чтобы получился адрес **API**.

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

![](/files/-LjttuDnePG6rBkM7iq3)

Так в чём же проблема?

Когда программа запускается, она ищет в записи **IAT** значение, чтобы сложить его с **IMAGEBASE** и найти строку, чтобы рассчитать адрес, но сейчас значение поломано, потому что при дампинге был сохранен итоговый адрес, и программа будет "падать" при запуске, и будет неспособна правильно заполнить **IAT**.

Хорошо, чтобы закончить с этой темой, давайте подведём итог. Идея состоит в том, чтобы исправить **IAT** и восстановить все эти смещения, которые указывали на строки с именами **API**. Это не надо делать вручную, так как так будет очень долго. Чтобы сделать это быстрее, будем использовать утилиту под названием **SCYLLA**.

Забрать её можно здесь.

<https://tuts4yoututs4you.com/download.php?view.3503>

Пароль на архив **RAR** равен **tuts4you**

![](/files/-LjttuE-zwV2QrDoR8Nx)

Я запускаю нашу распакованную **SCYLLA**.

![](/files/-LjpguvUIkM-tpqOmLTX)

В пункте **ATTACH TO ACTIVE PROCESS** из выпадающего меню я выбираю процесс упакованного файла, который остановлен в **IDA** на **OEP**.

![](/files/-LjttuEKFN4m2Xjn_LXQ)

Теперь меняем в программе **OEP** на значение **401000**.

![](/files/-LjttuETP0Ds3rKcJfu3)

И нажимаем кнопку **IAT AUTOSEARCH**.

![](/files/-LjttuEYgYB_EtyYr0Zc)

Программа говорит нам, что таблица **IAT** начинается по адресу **0x403184** и её размер равен **0x108**.

После этого, давайте нажмём кнопку **GET IMPORTS**.

![](/files/-LjttuEedEPWrYosABta)

Видим, что **SCYLLA** нашла все адреса, за исключением трёх вхождений. Она показывает плохие записи после нажатия кнопки **SHOW INVALID**.

![](/files/-Ljpguvd6XT7GakZKWb8)

С другой стороны, видим, что смещение **3238** в упакованном файле принадлежало, соответственно, функции **GetModuleHandleA** и мы знали про это. Программа очень правильно рассчитало значение. Мы можем посмотреть в упакованном файле недействительные адреса записи **0x403248** в дальнейшем, чтобы увидеть, что они собой представляют.

![](/files/-LjpguvfjWhvq7ynCu3m)

Видим, что эта запись принадлежит библиотеке **COMCTRL32**.

И если я сделаю правый щелчок на неправильных записях в **SCYLLA** и выберу **SCYLLA PLUGIN → PE COMPACT**, она исправит эти ошибки.

![](/files/-LjttuFGJD5eUDp4QBra)

Теперь записи совпадают с теми, которые мы только что видели.

![](/files/-LjpguvjQdMtQvlQqG3w)

Если нажмём кнопку **SHOW SUSPECT**, можем увидеть, верны ли эти два подозрительных вызова по адресам **0x403258** и **0x403278**.

![](/files/-LjttuF_ltZw4d4-71wq)

Да, они получаются правильными. Так что, теперь, можем нажать кнопку **FIX DUMP**.

![](/files/-LjpguvnZQ68XI2vhVJU)

**SCYLLA** сохранит записи в починенный файл **PEPE-COPY\_SCY.EXE**, и теперь видно, что он работает.

![](/files/-Ljpguvpiozw-b77ye4n)

Открыв этот распакованный файл в **IDA**, видим, что теперь **OEP** начинается по адресу **0x401000** и что имена похожи на имена **API** как в исходном файле, так что всё рассчитались правильно.

![](/files/-LjpguvryXtLgUkTdbyf)

![](/files/-LjpguvtA26NSQUGgz4P)

Таблица **IAT** выглядит также хорошо, как и у исходного файла.

Хорошо, мы распаковали наш первый и простой упаковщик. Позже мы увидим другие, более сложные упаковщики.

До встречи в **16**-й главе.

Автор оригинального текста — Рикардо Нарваха.

Перевод и адаптация на английский язык — IvinsonCLS.

Перевод и адаптация на русский язык — Яша Яшечкин.

Перевод специально для форума системного и низкоуровневого программирования - WASM.IN

22.09.2017

[**Источник: ricardonarvaja.info**](http://ricardonarvaja.info/WEB/IDA%20DESDE%20CERO/CURSO%20DE%20IDA%20TUTES/15-INTRODUCCION%20AL%20REVERSING%20CON%20IDA%20PRO%20DESDE%20CERO.docx)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://yutewiyof.gitbook.io/intro-rev-ida-pro/chast-15.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
