workspace/research/

Research

研究笔记、实验记录与学习资料。

  • 2.4x 的 tcache 机制分析 glibc

    简述

    在 2.39 到 2.40 中,malloc.c 并未发生变化,因此我们这里主要讲一些 2.41 到 2.43 的 tcache 相关的一些小细节 在这三个版本中,主要变化可以简单概括为

    • 2.41:
      • calloc 可以分配 tcache 块
      • 小 chunk 被 free 后会直接进入 small bin
    • 2.42
      • large_tcache 的引入
    • 2.43
      • tcache 扩容以补偿 fastbin 删除的性能问题
      • large_tcache 分配改为需要精确 chunk_size
      • mmap chunk 可以进入 tcache

    因为 tcache 初始化时机这几个版本一直改来改去的很乱,只做简述 以下为细分的分析,我会粘贴一些源码辅助理解

    tcache 基本机制

    tcache 结构体的变化

    在 glibc 2.42版本中,tcache_perthread_struct 结构进行了调整

    • 2.41
    /* We overlay this structure on the user-data portion of a chunk when
       the chunk is stored in the per-thread cache.  */
    typedef struct tcache_entry
    {
      struct tcache_entry *next;
      /* This field exists to detect double frees.  */
      uintptr_t key;
    } tcache_entry;
    
    /* There is one of these for each thread, which contains the
       per-thread cache (hence "tcache_perthread_struct").  Keeping
       overall size low is mildly important.  Note that COUNTS and ENTRIES
       are redundant (we could have just counted the linked list each
       time), this is for performance reasons.  */
    typedef struct tcache_perthread_struct
    {
      uint16_t counts[TCACHE_MAX_BINS];
      tcache_entry *entries[TCACHE_MAX_BINS];
    } tcache_perthread_struct;
    
    static __thread bool tcache_shutting_down = false;
    static __thread tcache_perthread_struct *tcache = NULL;
    
    • 2.42
    /* We overlay this structure on the user-data portion of a chunk when
       the chunk is stored in the per-thread cache.  */
    typedef struct tcache_entry
    {
      struct tcache_entry *next;
      /* This field exists to detect double frees.  */
      uintptr_t key;
    } tcache_entry;
    
    /* There is one of these for each thread, which contains the
       per-thread cache (hence "tcache_perthread_struct").  Keeping
       overall size low is mildly important.  The 'entries' field is linked list of
       free blocks, while 'num_slots' contains the number of free blocks that can
       be added.  Each bin may allow a different maximum number of free blocks,
       and can be disabled by initializing 'num_slots' to zero.  */
    typedef struct tcache_perthread_struct
    {
      uint16_t num_slots[TCACHE_MAX_BINS];
      tcache_entry *entries[TCACHE_MAX_BINS];
    } tcache_perthread_struct;
    

    entry 的部分基本没有变化,这里主要变化还是原本的 counts 数组变成了 num_slots 数组 原本的 counts 数组表示对应索引下 tcache 链表的长度,现在 num_slots 数组中变为了对应索引下设剩下的空槽位

  • Perf与简单的侧信道攻击 CTF

    perf

    简介

    perf 是 Linux 系统性能分析工具集,全称是 Performance Event Counters 它基于 Linux 内核的 perf_events 子系统,能够提供硬件和软件层面的性能分析能力 我们这里会用到它的一些功能以获取一些硬件事件的信息,因此,你必须确保自己的虚拟机支持 PMU 功能

    准备perf

    事前准备

    首先确定你的设备支持 PMU 功能,如果条件允许,实体机上使用 perf 会方便很多,如果你使用的是 wsl2 作为使用的虚拟机,请在设置中开启 性能计数器 ,并使用除 ubuntu 以外的系统,因为 wsl2 对内核的魔改会导致一些兼容性问题,我捣鼓了两天也没能完美解决,可以在 wsl2 上选择其他 Linux 进行尝试,或者换用 VMware ,在使用VMware时,请在硬件设置里,添加上虚拟化 CPU 性能计数器,并禁用所有HyperV相关的设置,并关闭虚拟化保护 包括(仅限VMware使用者,wsl2 不要改):

    • Windows安全中心 -> 设备安全性 -> 内核隔离 -> 内存完整性/本地安全机构保护
    • Windows功能 -> Hyper-V/Virtual Machine Platform/Windows虚拟机监控程序平台

    perf安装

    安装 perf 可以通过

    sudo apt-get install linux-tools-generic
    

    相关设置

    使用权限

    等安装完成后并不能直接使用,你需要先查看

    cat /proc/sys/kernel/perf_event_paranoid
    

    这个perf_event_paranoid设置了运行时权限相关的内容,建议修改成小于等于1的值

    sudo sh -c 'echo -1 > /proc/sys/kernel/perf_event_paranoid'
    
    CPU核心与内存分配

    此时可以尝试一下使用

Terminal

C0nvR3 Lab terminal ready. Type help for commands.