> 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**, стараясь объяснить их в этой главе.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjpgtXYi2m-9DJDfnIk%2F-LjpguuSPrve426wz5BW%2F15-01.png?generation=1563195326715690\&alt=media)

Мы снова попадаем в **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**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-LjttuAkmCtfV1EKbITa%2F02.png?generation=1563265855071200\&alt=media)

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-LjttuAwc19Jh_0AnEGN%2F03.png?generation=1563265867483664\&alt=media)

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjpgtXYi2m-9DJDfnIk%2F-LjpguunYwXOJ7NkYnzl%2F15-04.png?generation=1563195326586046\&alt=media)

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjpgtXYi2m-9DJDfnIk%2F-LjpguurU98rzholNsFP%2F15-05.png?generation=1563195326646725\&alt=media)

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjpgtXYi2m-9DJDfnIk%2F-LjpguutENNyW7DP_yLS%2F15-06.png?generation=1563195326912473\&alt=media)

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjpgtXYi2m-9DJDfnIk%2F-Ljpguuv44yt_VkGbS6P%2F15-07.png?generation=1563195326501686\&alt=media)

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

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjpgtXYi2m-9DJDfnIk%2F-LjpguuxP6oprBhi08nc%2F15-08.png?generation=1563195327029440\&alt=media)

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjpgtXYi2m-9DJDfnIk%2F-Ljpguv2yuxK7zGRwq3x%2F15-09.png?generation=1563195326752194\&alt=media)

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjpgtXYi2m-9DJDfnIk%2F-Ljpguv4R6Jk3cD7yaJ1%2F15-10.png?generation=1563195327032794\&alt=media)

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjpgtXYi2m-9DJDfnIk%2F-Ljpguv63Oh_CYvULfTV%2F15-11.png?generation=1563195326824845\&alt=media)

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

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

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

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

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

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjpgtXYi2m-9DJDfnIk%2F-Ljpguv8uJ6dRCqVTKHG%2F15-12.png?generation=1563195327245716\&alt=media)

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-LjttuCUaR_3N6x6MY41%2F13.png?generation=1563265875592726\&alt=media)

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

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-LjttuCe2k0ah2-H3ipN%2F14.png?generation=1563265860393721\&alt=media)

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

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

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-LjttuCmaQv9L5MvIVN2%2F15.png?generation=1563265859395291\&alt=media)

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjpgtXYi2m-9DJDfnIk%2F-LjpguvGVbOIhubv9eer%2F15-16.png?generation=1563195326756939\&alt=media)

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-LjttuCzu5xS4TACcPsl%2F17.png?generation=1563265867606123\&alt=media)

И каждый блок складывается с содержимым **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**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-LjttuDKzz58Dt6DoTwF%2F18.png?generation=1563265869268042\&alt=media)

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

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjpgtXYi2m-9DJDfnIk%2F-LjpguvMVNupJUr9-Ssd%2F15-19.png?generation=1563195327489686\&alt=media)

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-LjttuDcG9X1bcPPwxxn%2F20.png?generation=1563265850540189\&alt=media)

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

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-LjttuDnePG6rBkM7iq3%2F21.png?generation=1563265858543518\&alt=media)

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

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

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

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

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

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-LjttuE-zwV2QrDoR8Nx%2F22.png?generation=1563265876704363\&alt=media)

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjpgtXYi2m-9DJDfnIk%2F-LjpguvUIkM-tpqOmLTX%2F15-23.png?generation=1563195327222935\&alt=media)

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-LjttuEKFN4m2Xjn_LXQ%2F24.png?generation=1563265860487044\&alt=media)

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-LjttuETP0Ds3rKcJfu3%2F25.png?generation=1563265857482344\&alt=media)

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-LjttuEYgYB_EtyYr0Zc%2F26.png?generation=1563265879377485\&alt=media)

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

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-LjttuEedEPWrYosABta%2F27.png?generation=1563265877702263\&alt=media)

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjpgtXYi2m-9DJDfnIk%2F-Ljpguvd6XT7GakZKWb8%2F15-28.png?generation=1563195326670163\&alt=media)

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjpgtXYi2m-9DJDfnIk%2F-LjpguvfjWhvq7ynCu3m%2F15-29.png?generation=1563195326501509\&alt=media)

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

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-LjttuFGJD5eUDp4QBra%2F30.png?generation=1563265859328514\&alt=media)

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjpgtXYi2m-9DJDfnIk%2F-LjpguvjQdMtQvlQqG3w%2F15-31.png?generation=1563195326834521\&alt=media)

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-LjttuF_ltZw4d4-71wq%2F32.png?generation=1563265872766375\&alt=media)

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjpgtXYi2m-9DJDfnIk%2F-LjpguvnZQ68XI2vhVJU%2F15-33.png?generation=1563195326844371\&alt=media)

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjpgtXYi2m-9DJDfnIk%2F-Ljpguvpiozw-b77ye4n%2F15-34.png?generation=1563195326664896\&alt=media)

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjpgtXYi2m-9DJDfnIk%2F-LjpguvryXtLgUkTdbyf%2F15-35.png?generation=1563195326490825\&alt=media)

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjpgtXYi2m-9DJDfnIk%2F-LjpguvtA26NSQUGgz4P%2F15-36.png?generation=1563195326706763\&alt=media)

Таблица **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)
