1. 程式人生 > 實用技巧 >House of Lore

House of Lore

原理

    /*
       If a small request, check regular bin.  Since these "smallbins"
       hold one size each, no searching within bins is necessary.
       (For a large request, we need to wait until unsorted chunks are
       processed to find best fit. But for small ones, fits are exact
       anyway, so we can check now, which is faster.)
     
*/ if (in_smallbin_range(nb)) { // 獲取 small bin 的索引 idx = smallbin_index(nb); // 獲取對應 small bin 中的 chunk 指標 bin = bin_at(av, idx); // 先執行 victim= last(bin),獲取 small bin 的最後一個 chunk // 如果 victim = bin ,那說明該 bin 為空。 // 如果不相等,那麼會有兩種情況 if ((victim = last(bin)) != bin) {
// 第一種情況,small bin 還沒有初始化。 if (victim == 0) /* initialization check */ // 執行初始化,將 fast bins 中的 chunk 進行合併 malloc_consolidate(av); // 第二種情況,small bin 中存在空閒的 chunk else { // 獲取 small bin 中倒數第二個 chunk 。 bck = victim->bk;
// 檢查 bck->fd 是不是 victim,防止偽造 if (__glibc_unlikely(bck->fd != victim)) { errstr = "malloc(): smallbin double linked list corrupted"; goto errout; } // 設定 victim 對應的 inuse 位 set_inuse_bit_at_offset(victim, nb); // 修改 small bin 連結串列,將 small bin 的最後一個 chunk 取出來 bin->bk = bck; bck->fd = bin; // 如果不是 main_arena,設定對應的標誌 if (av != &main_arena) set_non_main_arena(victim); // 細緻的檢查 check_malloced_chunk(av, victim, nb); // 將申請到的 chunk 轉化為對應的 mem 狀態 void *p = chunk2mem(victim); // 如果設定了 perturb_type , 則將獲取到的chunk初始化為 perturb_type ^ 0xff alloc_perturb(p, bytes); return p; } } }

通過修改small bin的bk指標達到任一地址分配,其中要繞過的檢測就是bck->fd!=victim

由於small bin遍歷為bk迴圈,所以需要覆蓋bk指標,接下來我們來通過原始碼來實驗