> 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-48.md).

# Часть 48

Мы будем стараться продолжать обсуждать распределение, чтобы увидеть сможем ли мы понять логику распределения и увидеть, что говорит программа, если распределение происходит в **LFH** или в **СТАНДАРТНОЙ КУЧЕ**.

Мы будем продолжать использовать исполняемый файл из того же практического упражнения.

Мы загружаем исполняемый файл вне **IDA** из консоли, не используя скрипт **PYTHON**.

Мы вводим номер, который нас просит программа **(1073741828)**, присоединяем **WINDBG** к **IDA** как отладчик, помещаем **BP** на функцию **MALLOC** и нажимаем клавишу **ENTER**.

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4FBgAVCwZmIy29b%2F48-02.png?generation=1563225042767509\&alt=media)

Если мы трассируем вход в функцию **MALLOC** с помощью клавиши **F7** мы увидим, что размер помещается в регистр **ESI**. Программа сравнивает это значение. Если размер больше чем значение **0xFFFFFFE0**, то, так как в нашем случае это значение равно **0x10**, то у нас нет проблем. Программа помещает в стек размер как аргумент и прямо там мы видим, что программа помещает в стек, в моём случае, значение **0x240000**. Это одна из куч, поэтому мы уже знаем, что программа будет работать с ней.

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

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

Здесь мы можем создать функцию с помощью правого щелчка и выбрав пункт **CREATE FUNCTION** и переименовать аргументы, которые были размером, нулем и базой кучи.

Это структура кучи. Я оставляю её для копирования и вставки.

```
# +0x000 Entry : _HEAP_ENTRY
# +0x008 SegmentSignature : Uint4B
# +0x00c SegmentFlags : Uint4B
# +0x010 SegmentListEntry : _LIST_ENTRY
# +0x018 Heap : Ptr32 _HEAP
# +0x01c BaseAddress : Ptr32 Void
# +0x020 NumberOfPages : Uint4B
# +0x024 FirstEntry : Ptr32 _HEAP_ENTRY
# +0x028 LastValidEntry : Ptr32 _HEAP_ENTRY
# +0x02c NumberOfUnCommittedPages : Uint4B
# +0x030 NumberOfUnCommittedRanges : Uint4B
# +0x034 SegmentAllocatorBackTraceIndex : Uint2B
# +0x036 Reserved : Uint2B
# +0x038 UCRSegmentList : _LIST_ENTRY
# +0x040 Flags : Uint4B
# +0x044 ForceFlags : Uint4B
# +0x048 CompatibilityFlags : Uint4B
# +0x04c EncodeFlagMask : Uint4B
# +0x050 Encoding : _HEAP_ENTRY
# +0x058 PointerKey : Uint4B
# +0x05c Interceptor : Uint4B
# +0x060 VirtualMemoryThreshold : Uint4B
# +0x064 Signature : Uint4B
# +0x068 SegmentReserve : Uint4B
# +0x06c SegmentCommit : Uint4B
# +0x070 DeCommitFreeBlockThreshold : Uint4B
# +0x074 DeCommitTotalFreeThreshold : Uint4B
# +0x078 TotalFreeSize : Uint4B
# +0x07c MaximumAllocationSize : Uint4B
# +0x080 ProcessHeapsListIndex : Uint2B
# +0x082 HeaderValidateLength : Uint2B
# +0x084 HeaderValidateCopy : Ptr32 Void
# +0x088 NextAvailableTagIndex : Uint2B
# +0x08a MaximumTagIndex : Uint2B
# +0x08c TagEntries : Ptr32 _HEAP_TAG_ENTRY
# +0x090 UCRList : _LIST_ENTRY
# +0x098 AlignRound : Uint4B
# +0x09c AlignMask : Uint4B
# +0x0a0 VirtualAllocdBlocks : _LIST_ENTRY
# +0x0a8 SegmentList : _LIST_ENTRY
# +0x0b0 AllocatorBackTraceIndex : Uint2B
# +0x0b4 NonDedicatedListLength : Uint4B
# +0x0b8 BlocksIndex : Ptr32 Void
# +0x0bc UCRIndex : Ptr32 Void
# +0x0c0 PseudoTagEntries : Ptr32 _HEAP_PSEUDO_TAG_ENTRY
# +0x0c4 FreeLists : _LIST_ENTRY
# +0x0cc LockVariable : Ptr32 _HEAP_LOCK
# +0x0d0 CommitRoutine : Ptr32 long
# +0x0d4 FrontEndHeap : Ptr32 Void
# +0x0d8 FrontHeapLockCount : Uint2B
# +0x0da FrontEndHeapType : UChar
# +0x0dc Counters : _HEAP_COUNTERS
# +0x130 TuningParameters : _HEAP_TUNING_PARAMETERS
```

Мы не будем создавать структуры в **IDA** со всеми полями. Мы только создадим пустую структуру, чтобы переименовывать только те поля, которые мы используем.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4FfEeMjxUOAqpx6%2F48-05.png?generation=1563225042481826\&alt=media)

Я создаю структуру через вкладку **STRUCTURES** с помощью клавиши **INSERT** и затем расширяю её до значения **0x130** байт. Позже я увижу, нужно ли мне расширить её ещё больше.

Мы уже знаем как это сделать. Я добавляю однобайтовое поле, помещая курсор на слово **ENDS** и нажимаю клавишу **D**, а затем нажимаю правую кнопку, и выбираю пункт **EXPAND**, и ввожу значение **0x12F**.

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4Fu8PJQR2UVs-In%2F48-07.png?generation=1563225042735861\&alt=media)

Я нахожусь в структуре размером **0x130** байт. Структура будет немного больше из-за длины последнего поля, но позже мы увидим всё ли правильно.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4FzOlzvyaTT1rxm%2F48-08.png?generation=1563225042681615\&alt=media)

Здесь программа использует смещение **44**, а ниже смещение **5C**. Я нажимаю **T** на обоих полях, и выбираю структуру **HEAP**.

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

Теперь я должен определить эти поля в структуре.

> **# +0x044 FORCEFLAGS : UINT4B**
>
> \# +0x048 CompatibilityFlags : Uint4B
>
> \# +0x04c EncodeFlagMask : Uint4B
>
> \# +0x050 Encoding : \_HEAP\_ENTRY
>
> \# +0x058 PointerKey : Uint4B
>
> **# +0x05C INTERCEPTOR : UINT4B**

Это два поля по **4** байты. Я переименую их. Я иду по смещению **0x44** и нажимаю **D** до тех пор пока не появятся буквы **DD**.

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

И я переименую их.

Хорошо. Мы не имеем представление что это и для чего это нужно, но по крайнер мере это выглядит симпатично.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4GGw9D7737cS86w%2F48-11.png?generation=1563225042446772\&alt=media)

Очевидно, не все поля или не всё, что делает программа мы будем интерпретировать, но постепенно мы увидим, что делает программа.

Как только мы дотрассируем до этого места, регистр **EBX** принимает значение базы кучи, **240000** в моем случае. Я могу пойти пойти этому адресу и назначить этому адресу структуру кучи, которая на данный момент что-то имеет.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4GMQRrPNUgbS9m-%2F48-12.png?generation=1563225043107802\&alt=media)

С помощью сочетания **ALT + Q** или **CONVERT TO STRUCT VARIABLE** мы можем конвертировать данные в структуру.

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

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

Выглядит не очень симпатично, но там видны поля **FORCEFLAGS** и **INTERCEPTOR** равные нулю.

Это совпадает c результатом отладчика

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4Gc4WaykgvFZE6D%2F48-15.png?generation=1563225043203528\&alt=media)

И с помощью такой команды видны значения

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4GkWbDAlZ7M8mrG%2F48-16.png?generation=1563225042446740\&alt=media)

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

Я скопировал исполняемый файл в другую папки не закрывая предыдущий файл, чтобы проверить его. Я открываю второй файл непосредственно во второй **IDA** без присоединения, но прямо внутри неё и это значение изменяться на **0x40000060**. Это значение, указывает на то отлаживается ли программа.

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

Это вывод для файла, который отлаживается.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4H-LRLnSL6Gu0J2%2F48-19.png?generation=1563225042867583\&alt=media)

А это вывод для файла, который просто отрыт в отладчике.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4H6ReyZ2xGp5vAI%2F48-20.png?generation=1563225042552738\&alt=media)

Здесь отладчик говорит, что среди прочих вещей, этот флаг может быть использован как **АНТИОТЛАДОЧНАЯ ТЕХНИКА**.

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

Аргумент, который был равен нулю повторно используется в инструкции **OR** с полем **FORCEFLAGS**. Таким образом, поскольку аргумент был равен нулю, это выражение будет также равно **FORCEFLAGS**.

И регистр **ECX**, который содержит переменную **INTERCEPTOR** сохраняет её в переменную **VAR\_C**, поэтому я переименовываю эту переменную, хотя я не нашел никаких объяснений для чего она нужна, но позже мы увидим, то что я увидел, это то что переменная не меняется если программа отлаживается или не равна нулю в обоих случаях.

Поскольку переменная **INTERCEPTOR** в моем случае равна нулю и регистр **ESI** равен нулю, программа переходит на красную стрелку так как значения равны.

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

Затем программа тестирует переменную **FORCEFLAGS**, которая равна нулю по отношению к константе **7D810F61**. Результат будет равен нулю и программа будет идти по красной стрелкой. (Если программа открыта в отладчике, то программа будет идти по зеленой стрелке)

Программа сравнивает, значения. Если размер равен нулю, а в нашем случае он равен **0x10**, поэтому программа пойдет сюда.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4HXzTRtsRdwqFZe%2F48-23.png?generation=1563225042513732\&alt=media)

Программа прибавляет к регистру **EAX** значение **0xF**, а затем исполняет инструкцию **AND** с параметром **-8**, что будет равно **0x18**. Это будет равно полному размеру, чтобы распределить добавленный заголовок и быть умноженным на **8**.

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

В регистре **EAX** остается значение полного размера, равное **18**.

Затем программа сохраняет в переменную **VAR\_8** это значение, поэтому я переименую эту переменную.

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

Затем программа читает поле **0xB8** которое является **BLOCKINDEX**, поэтому я переименую его в структуре и здесь я нажимаю **T** для того чтобы освежить информацию.

```
# +0x0B8 BLOCKSINDEX : PTR32 VOID
```

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

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

Поэтому это значение является указателем, которое равно **0x240150** в моём случае. Давайте запомним, что

```
shr eax, 3 ;Signed division by 8
```

И это то же самое что и знаковое деление переменной **SIZE\_FULL** на **8**. Помните также, что размер, который появился в заголовках как общий размер, нужно было умножить на **8**, чтобы найти общий размер блока.

Например, скопировав из предыдущего туториала поле **USERSIZE 0x10**, мы получим общий размер **0x3**, умножив который на **8**, мы получим общее количество байтов.

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

```
Python>hex(0x3*0x8)
0x18
```

Это обратная операция для переменной **SIZE\_FULL** для нахождения значения **0x3** при делении на **0x8**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4I34F1P_U6qdjdX%2F48-29.png?generation=1563225042601472\&alt=media)

Мы видим, что теперь программа начинает работать со структурой **BLOCKSINDEX**, которую мы видели в последнем туториале. (Следующее изображение из предыдущего туториала)

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

Поэтому мы можем создать новую пустую структуру из **0x24** байт, чтобы ввести последний **DWORD**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4IHqZ90Gr-37Vnz%2F48-31.png?generation=1563225042659727\&alt=media)

Поэтому сейчас я нажимаю **T** на инструкции и выбираю эту новую структуру.

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

Теперь я должен только переименовать поле, которое находится по смещению **0x4** в **ARRAYSIZE**.

Поскольку регистр **EAX** указывает на начало этой структуры, я могу пойти в память и назначить структуру с помощью **ALT + Q**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4IUbLDBpdfeBII5%2F48-33.png?generation=1563225042326903\&alt=media)

**ARRAYSIZE** равен **0x80** в этом случае, остальные поля по-прежнему не определены, поэтому все это выглядит некрасивым.

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

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

Мы находимся в этой части

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

Здесь **FULL SIZE** делится на **8**. Это значение присваивается переменной **BLOCKSIZE**. Мы все еще храним это значение в регистре **ECX**. Мы не сохраняем его, только сравниваем, и мы видим, что программа также делает, сравнивая с **ARRAYSIZE** так же, как и наши.

Программа вычитает **1** из значения **ARRAYSIZE**, получая значение **0x7F** и снова сравнивает результат со значением **0x3**, которое находится в регистре **ECX**.

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

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

Сейчас программа прочитает поле **0x14** структуры **BLOCKLIST**, которое называется **BASEINDEX**, поэтому я переименую его.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4IxiiaOmXTN-jBD%2F48-37.png?generation=1563225042442648\&alt=media)

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4JF4SgP_BX9E6C2%2F48-38.png?generation=1563225042385185\&alt=media)

Поскольку **BASEINDEX** равен **0**, регистр **ECX** по-прежнему продолжает быть равен значению **0x3** т.е. **BLOCKSIZE**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4JK4vnD53SgAzRk%2F48-39.png?generation=1563225042827668\&alt=media)

Поскольку поле **EXTRAITEM**, которое находится по смещению **0x8**, равно **1** (я не буду повторять, как переименовать поле в структуре), мы доходим до инструкции **ADD ECX, ECX**, где программа умножает на **2** значение **BLOCKSIZE**.

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

Затем программа использует смещение **0x20 LISTHINTS**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4JW7j-XLW6mGRxT%2F48-41.png?generation=1563225042640442\&alt=media)

При умножении **0x6** на **4** и сложение с указателем **LISTHINTS** в регистре **ESI** остаётся значение **0x24019C**.

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

**LISTHINTS** указывает на **FREELIST**, который является другим типом более простого распределения. Теперь мы посмотрим, что делает программа.

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

Таким образом, мы можем создать новую структуру из **8** байт. Но в моей **IDA** у меня уже это есть эта структура (если у вас её нет, то создайте её).

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4Junx2vT0tSVd-Q%2F48-45.png?generation=1563225042743575\&alt=media)

Т.е. если **LFH** выключен, у **BLINK** есть счетчик, а если он включен, то имеет указатель. **(HEAP\_BUCKET + 1)**

Хорошо. Вопрос здесь состоит в том, что программа тестирует регистр **AL**. Если он равен **1**, чтобы увидеть, является ли он счетчиком.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4Jz-p8BDQetaXDT%2F48-46.png?generation=1563225042625841\&alt=media)

Если **BLINK** равен **1**, программа переходит к этому зеленому блоку с вызовом функции **RTLPALLOCATEHEAP**, а если нет, как в моем случае, программа переходит на голубой блок, который идет в вызов **RTLPLOWFRAGHEAPALLOCFRONCONTEXT**.

Другими словами, есть некоторые вещи, которые мы видим в нашем случае, программа сравнивает размер **0x3** с **0x80**, и поскольку это значение меньше, а регистр **AL** из **BLINK** отличался от байта **0x1**, мы прибыли сюда к чему-то, что, по-видимому, обрабатывается **LFH**.

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

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

Регистр **ECX** имеет указатель, который был в **BLINK - 1** и в регистре **EDX** находится **USERSIZE 0x10**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4KKa5v91zcJP_Oc%2F48-49.png?generation=1563225042530945\&alt=media)

Поскольку в функции не отображаются переменные и функция основана на **EBP** (были переменными **EBP - X**), я изменил тип функции, поставив здесь галочку.

Напомним, что у **BLINK** было значение **HEAP\_BUCKET + 1**, другими словами, вычитая **1**, это будет равно **HEAP\_BUCKET**, поэтому я переименую переменную в **HEAP\_BUCKET**.

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

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

Другими словами, регистр **EDI** является базой структуры **HEAP\_BUCKET** которую я создал.

Кажется она имеет **0x3** байта.

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

Хорошо. **SIZEINDEX** равен **2**, программа помещает это значение в регистр **EAX**

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4KhxHDuqqRWKBaJ%2F48-53.png?generation=1563225042811608\&alt=media)

```
LEA EAX, DS:110H[EAX*4]
```

Программа умножает значение **0x2** на **4** и складывает полученное значение со значением **0x110** и затем вычитает из найденного значения **HEAP\_BUCKET** и сохраняет результат в переменную **VAR\_2C**.

Этот адрес, который сохраняется в переменную **VAR\_2C** является началом таблицы **LFH**, так как **HEAP\_BUCKETS** находится по смещению **0x110** и должен быть равен **8**, потому что поле находится внутри таблицы **BUCKETS**, поэтому в переменной **VAR\_2C** программа сохраняет значение **0x24ACF8**, которое было началом таблицы **LFH**.

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4KtbHyq-vY-NTeE%2F48-55.png?generation=1563225042538790\&alt=media)

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

То, что программа сейчас делает, это то, что говорит нам картинка. Программа пытаясь найти адрес **LFH** для этой структуры **BUCKET**, используя переменную **SIZEINDEX**.

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

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

Очевидно, мы находимся в этой части, только в моём случае переменная не равна единице и программа продолжает выполнение здесь.

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

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

Программа достигает инструкции **LEA**, где на данный момент регистр **EAX** равен нулю, поскольку он получается из умножения **0x3418** на **CONST\_CERO** и суммируется с регистром **ESI**, который хранит начало таблицы **LFH** и добавляет значение **0x310**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4LaFSLfa7VKyIhn%2F48-61.png?generation=1563225044131680\&alt=media)

Мы напомним, что смещение **0x310** из **LFH** это **\_HEAP\_LOCAL\_DATA**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4LhPVc_ymcQHJPw%2F48-62.png?generation=1563225043631081\&alt=media)

Это значение сохраняется в переменную **VAR\_44**. Я переименую это поле в **HEAP\_LOCAL\_DATA**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4Lpork5aX4KW5Z9%2F48-63.png?generation=1563225042901562\&alt=media)

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4LvZEBXilFFntnt%2F48-64.png?generation=1563225042765155\&alt=media)

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4M8Hb0RHSW87n1P%2F48-65.png?generation=1563225042858328\&alt=media)

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

Хорошо. Мы должны создать структуру для **HEAP\_LOCAL\_DATA**.

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

Я создаю структуру из **0x22** байт, хотя она наверняка будет намного больше, но пока пойдет и это.

По смещению **0x18** есть структуры. Их размер равен **0x128** байт.

```
[128] _HEAP_LOCAL_SEGMENT_INFO
```

Программа проходит через все эти **128** структур, используя **SIZEINDEX** как индекс, который умножается на **0x68**, а затем добавляет значение, чтобы найти адрес это структуры **SEGMENTINFO**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4MeDl2tNjlKKF2Y%2F48-67.png?generation=1563225042737445\&alt=media)

Это означает, что адрес **DIRECCION3** равен **HEAP\_LOCAL\_SEGMENT\_INFO**.

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

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

Поэтому мы будем создавать структуру больше чем **0x64** байта.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4N5CZtJ7CQtIhMg%2F48-70.png?generation=1563225042874333\&alt=media)

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

Хорошо. Внутри отладчика этого выглядит так.

```
ntdll!\_HEAP\_LOCAL\_SEGMENT\_INFO
+0x000 Hint : Ptr32 \_HEAP\_SUBSEGMENT
```

Первое поле, которое программа пытается использовать здесь, говорит, что это **HINT** .

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4NI5ThGPxATSkj_%2F48-72.png?generation=1563225044266358\&alt=media)

И программа сохранит это значение в переменную **VAR\_30**. Я переименовываю переменную в **HINT**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4NPA0nzoea9IcUQ%2F48-73.png?generation=1563225042828327\&alt=media)

Если значение **HINT** не равно нулю, программа ищет **ACTIVESUBSEGMENT**, что является следующим полем.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4NVA-VyrugNMJmr%2F48-74.png?generation=1563225043877646\&alt=media)

А если это поле равно нулю, программа переходит сюда

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4NdD_KXM0KOyWu7%2F48-75.png?generation=1563225042767106\&alt=media)

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

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

Хорошо. Мы находимся здесь.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4Nry1p8DPhkO0vE%2F48-76.png?generation=1563225043633645\&alt=media)

Мы будем переименовывать переменную **HINT** в **RESULTADO**, поскольку переменная может принимать три значения.

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

Картинка показывает нам три варианта. Сейчас же мы находимся в **HINT**.

Этот результат должен был бы быть **\_HEAP\_SUBSEGMENT**.

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

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

Здесь программа говорит мне, что **\_HEAP\_LOCAL\_SEGMENT\_INFO** находится в памяти по адресу **0x24B0F0** и что **0x282660** это структура **\_HEAP\_USERDATA\_HEADER** а по смещению **0x08** это структура **INTERLOCK\_SEQ**.

Мы уже подходим к концу. Фууууууууууууууууууххххххххххххх.

Здесь я добавляю новую структуру.

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

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

Здесь я вижу, что программа находит с помощью инструкции **LEA** адрес поля **\_INTERLOCK\_SEQ**

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4OhKMVnrFaenDq0%2F48-83.png?generation=1563225043667257\&alt=media)

На данный момент, я думаю что она состоит из **4** байтов.

Программа может прочитать поле как **WORD** или как **DWORD**, это сложно для имени. В моем случае, программа читает **DWORD** т.е. имеет значение **0x56000D** (**ЭТО ЗНАЧЕНИЕ ОЧЕНЬ ВАЖНО**)

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4OytpVNCjTz7-MP%2F48-85.png?generation=1563225043506005\&alt=media)

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

Я добавляю поле **SEQUENCE**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4PBEKAv_stGGrW6%2F48-87.png?generation=1563225050498006\&alt=media)

Программа тестирует регистр **DI** который хранит поле **OFFSETANDDEPTH**. Это поле в моём случае равно **0xD**.

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

Здесь программа читает поле **USERBLOCKS**, которое находится по смещению **0x4** структуры **HEAP\_SUBSEGMENT**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4PQcpTLYdpJgc_U%2F48-89.png?generation=1563225043544983\&alt=media)

Программа сравнивает регистр **EDX** который хранит **LOCALINFO** высчитанный с помощью указателя **HEAP\_SUBSEGMENT.LOCALINFO** и они должны быть одинаковыми.

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4PVDTRO2Nm7a2YV%2F48-90.png?generation=1563225050754615\&alt=media)

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

Хорошо. Я не собираюсь просчитывать все эти значения, но очевидно, что то, что программа делает, это получает первый свободный блок запрошенного размера из значений структуры **\_INTERLOCK\_SEQ**, и когда программа покинет этот блок, она сохранит его здесь.

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

Регистр **ECX** здесь равен значению **282918** и если я посмотрю список блоков с размером **0x10** с помощью команды.

```
!heap -flt s 0x10
```

В выводе блоки находятся здесь

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4Pm9FA4HlEzCqNi%2F48-93.png?generation=1563225043112369\&alt=media)

И это первое значение из этих **LFH**, потому что предыдущие размеры **0x10**, которые говорят что они **FREE(СВОБОДНЫЕ)**, имеют другую **LFH** младшего адреса, возможно, соответствующей другой куче.

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

Здесь по адресу чанка **0x282918** без заголовка, вычитается **8**, и остается адрес полного блока с заголовком **0x282910**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4PxBbhd1Sit8yGS%2F48-95.png?generation=1563225042871210\&alt=media)

Структура, которую мы ещё не добавили называется структурой **LFH**. Сейчас я сделаю это.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4Q2o7geXNkzeJlM%2F48-96.png?generation=1563225042895957\&alt=media)

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4Q8_noQClK8r5SG%2F48-97.png?generation=1563225042959043\&alt=media)

Теперь используется поле **0x24**, которое должно найти базовый адрес **КУЧИ** по адресу **0x240000**. Полученное значение помещается в регистр **ESI**.

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

**BLOCKUNITS** был равен **0x3** в инструкции **SHL EAX, 3**

Это похоже на умножение **8** поэтому

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4QJOgmH3oFjZ3V3%2F48-99.png?generation=1563225044315310\&alt=media)

И это то значение, что осталось в поле **USERSIZE**

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4QPzxmiw2wwwK5t%2F48-100.png?generation=1563225042832875\&alt=media)

И это значение программа сравнивает со значением **0x3F** . Поскольку оно меньше, программа идёт сюда.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4QTLDto6tcXxmII%2F48-101.png?generation=1563225043755234\&alt=media)

Здесь программа пишет в заголовок чанка **LFH**. Мы не сделали структуру.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4QZVQhBUBePz72J%2F48-102.png?generation=1563225042774898\&alt=media)

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4QiQUexqVCseFfd%2F48-104.png?generation=1563225043478634\&alt=media)

Программа перезаписывает **7** байт, меняя его со значения **0x80** на **0x88**.

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4QtcG1r9sWxYynd%2F48-106.png?generation=1563225042687245\&alt=media)

Сейчас блок обозначен как занятый. Если мы посмотрим следующий свободный блок по адресу **282928**

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4QyzKTo1i8dYvGy%2F48-107.png?generation=1563225042959641\&alt=media)

Свободные блоки - это блоки со значение **0x80**, а занятые со значением **0x88**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4R5aet1yt2mUvl0%2F48-108.png?generation=1563225043935655\&alt=media)

Вопрос состоит в том, что значение, которое находится в структуре **INTERLOCK\_SEQ** и которое определяет следующий блок для доставки находится в по адресу **0x282A78** (по смещению **0x8** от начала структуры **HEAP\_SUBSEGMENT**)

До этого значение было равно **56000D**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4RC6QPZlKdKnQJL%2F48-109.png?generation=1563225045297278\&alt=media)

А сейчас значение равно **59000C**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4RI7yLNT0aTBwS3%2F48-110.png?generation=1563225044633780\&alt=media)

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

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

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

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4RTH5cMgV7EU5Ug%2F48-113.png?generation=1563225050602338\&alt=media)

Это значение **0x282660 USERBLOCKS**, помещается в регистр **ESI**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4Rceq6h83BqbuW1%2F48-114.png?generation=1563225043313356\&alt=media) ![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4RhWPxR0k9A42VE%2F48-115.png?generation=1563225043584815\&alt=media)

Это означает, что в следующий раз, когда запрашивается размер **0x010**, программа поместит в **EDI** значение **0x59000C** если оно не перезаписано.

Программа помещает значение в регистр **EAX** и затем исполняет инструкцию **SHR EAX\*\***,0xD

2 **в** 0xD **степени =** 8192 **десятичных байт, т.е.** 0x2000\*\* в шестнадцатеричной системе

Другими словами, это эквивалентно значению **0x59000С** делённому на значение **0x2000**, что даёт мне результат **0x2C8**

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

К этому значению программа применяет инструкцию **AND** c параметром **0x7FFF8**

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT4Rtd3LCsAmSh8tO%2F48-117.png?generation=1563225042757265\&alt=media)

Затем программа добавляет регистр **ESI**, который равен **0x282660**

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

И это даём мне результат **0x282928**, что является следующим свободным

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

Это означает, что если есть переполнение, мы можем перезаписать эти данные переписав значение внутри структуры **INTERLOCK\_SEQ** и программа предоставит мне предыдущий блок, про который мы расскажем в следующей части.

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

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

Исправление ошибок и неточностей - репетитор и носитель испанского языка.

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

24.06.2018

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