Cached at:
06/29/26, 11:04 AM
# TL;DR
This article uses disassembly and the WinDbg debugging tool to reveal that the 8 "mystery bytes" that appear before the allocated address when `calloc` allocates memory in an x86 environment are actually the heap manager's entry header in Windows, containing information such as the current block size, previous block size, unused bytes, and flags.
---
## Background: Starting from the Previous Video
In the previous video "Let's Answer Ray's Question", we analyzed a piece of code by Raylib author Ramon Santamaria: the same C code, when compiled for x86 and x64 targets, produced different runtime results. One of the differences was that in the x86 version, there were an extra 8 bytes between the two string pointers allocated by `calloc`. At the time, we only gave a basic explanation and promised to dive deeper into the assembly-level details. This video is the first follow-up—specifically analyzing what those 8 bytes are.
If you haven't watched the previous video yet, please do (link in the description). This video assumes you already know the pattern in which those 8 bytes are generated and where they appear in the code.
---
## Method: Tracing from `calloc`
### Initial Assembly-Level Investigation
We opened the debugger, set a breakpoint at the first `calloc` call, then stepped into the disassembly code. In x86, instruction lengths are variable (unlike ARM). We saw `push` (pushing arguments), `call` (calling a function), and then through a jump table eventually reaching the actual `calloc` implementation.
After stepping through several jumps, we discovered that `calloc` is not an allocator implemented by the C runtime library itself; rather, it is a thin wrapper that directly calls the Windows system routine `RtlAllocateHeap` (located in NTDLL). This is an important clue: it means we can use Windows' built-in heap debugging tools to observe the allocation behavior without having to delve into the internal implementation of the C runtime library.
### Using WinDbg's `!heap` Command
Exiting the disassembly, we returned to just before the allocation of string 02, after string 01 had already been allocated at address `0xE77320`. The address of those 8 mystery bytes is `0xE77318`. In WinDbg, execute:
``
!heap -x 0xE77320
``
The output shows:
- This address belongs to the unique process heap.
- The `size` is `0x10` (i.e., 16 bytes).
- The `prev size` is `0x18` (24 bytes).
- The `unused` is `8` bytes.
- There are also some flags.
This information directly corresponds to the 8 bytes we just saw. It is evident that the Windows heap manager treats these 8 bytes as the header of the heap allocation entry, containing the size of the current block, the size of the previous block, and some metadata.
---
## In-Depth Analysis: Heap Entry Structure
### Using the `dt` Command to Display the Structure
WinDbg can load debugging symbols for NTDLL, so we can use the `dt` command to view the heap entry type. Assuming the heap entry type is named `_HEAP_ENTRY`, but the actual command requires an address. However, the author demonstrated in the video that `dt _HEAP_ENTRY` directly displays the structure definition. The structure looks roughly like this (based on transcription):
- `Size`: the size of the current block (in units of 16 bytes? This needs verification, but the transcript says `size` is 0x10 which is 16 bytes)
- `PreviousSize`: the size of the previous block
- `UnusedBytes`: the number of unused bytes
- `SmallTagIndex` and other flag fields
It is this 8-byte structure that allows the heap manager to know the size of each allocated block, the addresses of preceding and following blocks, thus supporting memory allocation and deallocation.
### Interpreting the Specific Values
Taking the 8 bytes we obtained (at address `0xE77318`) as an example, their contents (hexadecimal) might be arranged as:
- 2 bytes: `size` (current block size)
- 2 bytes: `prev size` (previous block size)
- 1 byte: `segment index`
- 1 byte: `flags`
- 1 byte: `unused bytes`
- 1 byte: `small tag index`
However, the exact layout varies depending on the Windows version and heap implementation. The important point is that these 8 bytes are not generated at the C language level; they are a header automatically attached to each allocated block by the Windows heap manager.
---
## Verification: Consistent with Our Guess
Our initial intuition was correct: these 8 bytes are the header of the allocated block, used for heap management. Because `calloc` calls the Windows heap, every allocation has such an entry prefixed. In the x64 version, due to the different structure of the 64-bit heap manager (the heap entry size might be 16 bytes or something else), combined with address alignment and header size variations, the same phenomenon is not seen in the x64 code.
Additionally, through `!heap -x` we can see the complete information of the allocation entry, including the number of unused bytes (`unused` is 8), which exactly matches the space reserved by the heap manager after `calloc` allocates an 8-byte string.
---
## Summary
Those 8 mystery bytes are not an error, nor garbage produced by the compiler or linker. They are the heap entry header placed before each allocated block by the Windows heap manager. Its purpose is to record the size of the current block, the size of the previous block, and other metadata, facilitating memory management (such as coalescing free blocks, checking for heap corruption, etc.).
By reading the assembly call chain, we located `RtlAllocateHeap`, and then used WinDbg's `!heap` and `dt` commands to visually see this structure. The entire process demonstrates how to start from a "strange phenomenon" and, using system tools and low-level debugging techniques, arrive at a reasonable explanation.
---
Source: https://www.youtube.com/watch?v=GZqB4D_Do38