记录一次tcache调试

说明

根据这篇文章的内容结合glibc-2.27对tcache的分配和释放做了一次调试实验。

测试代码

$ cat t2.c 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(){
    
    void *p = malloc(112);
    memset(p, 'A', 112);
    free(p);
    void *p2 = malloc(112);
    free(p2);
}
$ gcc t2.c -o t2 -g

$ ldd --version
ldd (Ubuntu GLIBC 2.27-3ubuntu1) 2.27
...
$ uname -a
Linux ubuntu 5.3.0-51-generic #44~18.04.2-Ubuntu SMP Thu Apr 23 14:27:18 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

实验

1. 获取tcache_perthread_struct 地址

gdb t2
b main
r
b *tcache_init+144
c
p victim
set $tcache_0 = victim

输出:
gdb-peda$ b *tcache_init+144
Breakpoint 2 at 0x7ffff7a7a4f0: file malloc.c, line 3005.
gdb-peda$ c
=> 0x7ffff7a7a4f0 <tcache_init+144>:    mov    rax,QWORD PTR [rip+0x354881]        # 0x7ffff7dced78
...
Breakpoint 2, tcache_init () at malloc.c:3005
3005          tcache = (tcache_perthread_struct *) victim;
gdb-peda$ p victim
$1 = (void *) 0x555555756010
gdb-peda$ set $tcache_0 = victim

tcache分的地址为:0x555555756010


断点说明:
b *tcache_init+144 用于定位tcache指针

=> 0x7ffff7a7a4f0 <tcache_init+144>:    mov    rax,QWORD PTR [rip+0x354881]        # 0x7ffff7dced78
# ...
Breakpoint 2, tcache_init () at malloc.c:3005
3005          tcache = (tcache_perthread_struct *) victim;
# ------------------------------------------------------------------------------------------------

2. 获取第一次分配的内存地址

b *_int_malloc+366
c
reg rax
b *main+26
c
p p
p $rax

输出:
gdb-peda$ reg rax
RAX: 0x555555756260 --> 0x0
gdb-peda$ b *main+26
Breakpoint 4 at 0x5555555546f4: file t2.c, line 8.
gdb-peda$  c
[-------------------------------------code-------------------------------------]
   0x5555555546e7 <main+13>:    call   0x5555555545b0 <malloc@plt>
   0x5555555546ec <main+18>:    mov    QWORD PTR [rbp-0x10],rax
   0x5555555546f0 <main+22>:    mov    rax,QWORD PTR [rbp-0x10]
=> 0x5555555546f4 <main+26>:    mov    edx,0x70
   0x5555555546f9 <main+31>:    mov    esi,0x41
   0x5555555546fe <main+36>:    mov    rdi,rax
   0x555555554701 <main+39>:    call   0x5555555545a0 <memset@plt>
   0x555555554706 <main+44>:    mov    rax,QWORD PTR [rbp-0x10]
[------------------------------------stack-------------------------------------]
...
Breakpoint 4, 0x00005555555546f4 in main () at t2.c:8
8       memset(p, 'A', 112);

gdb-peda$ p p
$2 = (void *) 0x555555756260
gdb-peda$ p $rax
$3 = 0x555555756260

第一次malloc出的地址:0x555555756260


断点说明:
b *_int_malloc+366 定位到_int_malloc的return位置,从rax中获取malloc分配的内存地址

=> 0x7ffff7a7843e <_int_malloc+366>:    ret    

# static void *
# _int_malloc (mstate av, size_t bytes)
# {
# ...
#   checked_request2size (bytes, nb);

#   if (__glibc_unlikely (av == NULL))
#     {
#       void *p = sysmalloc (nb, av);
#       if (p != NULL)
#   alloc_perturb (p, bytes);
#       return p;
#     }
#     ...
# }

b *main+26 回到main函数中查看malloc出的内存地址
# gdb-peda$ disassemble main
# Dump of assembler code for function main:
# ...
   0x00005555555546e7 <+13>:    call   0x5555555545b0 <malloc@plt>
   0x00005555555546ec <+18>:    mov    QWORD PTR [rbp-0x10],rax
   0x00005555555546f0 <+22>:    mov    rax,QWORD PTR [rbp-0x10]
=> 0x00005555555546f4 <+26>:    mov    edx,0x70

3. 查看释放tcache的位置

b * __libc_free+1273
c
p *(tcache_perthread_struct *)$tcache_0
n
p *(tcache_perthread_struct *)$tcache_0
n
p *(tcache_perthread_struct *)$tcache_0

输出:

gdb-peda$ b * __libc_free+1273
Breakpoint 5 at 0x7ffff7a7be49: file malloc.c, line 2931.
gdb-peda$ c

=> 0x7ffff7a7be49 <__GI___libc_free+1273>:  mov    QWORD PTR [rsi+0x40],r12
...
Breakpoint 5, tcache_put (tc_idx=0x6, chunk=0x555555756250) at malloc.c:2931
2931      tcache->entries[tc_idx] = e;
gdb-peda$ p *(tcache_perthread_struct *)$tcache_0
$4 = {
  counts = '\000' <repeats 63 times>, 
  entries = {0x0 <repeats 64 times>}
}

gdb-peda$ n
...
2932      ++(tcache->counts[tc_idx]);
gdb-peda$ p *(tcache_perthread_struct *)$tcache_0
$5 = {
  counts = '\000' <repeats 63 times>, 
  entries = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x555555756260, 0x0 <repeats 57 times>}
}

gdb-peda$ n
gdb-peda$ p *(tcache_perthread_struct *)$tcache_0
$6 = {
  counts = "\000\000\000\000\000\000\001", '\000' <repeats 56 times>, 
  entries = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x555555756260, 0x0 <repeats 57 times>}
}

回收第一次malloc的内存到 tcache.entrise[6]



断点说明:
b * __libc_free+1273 定位到tcache_put函数(内联)
=> 0x7ffff7a7be49 <__GI___libc_free+1273>:  mov    QWORD PTR [rsi+0x40],r12
...
Breakpoint 5, tcache_put (tc_idx=0x6, chunk=0x555555756250) at malloc.c:2931
2931      tcache->entries[tc_idx] = e;

4. 查看tcache第二次被取出

b *main+61
c
delete 1-7
b *__libc_malloc+401
c
p *(tcache_perthread_struct *)$tcache_0
s
s
s
p *(tcache_perthread_struct *)$tcache_0
s
p *(tcache_perthread_struct *)$tcache_0
b *main+74
c
p p2


输出:
gdb-peda$ b *main+61
Breakpoint 6 at 0x555555554717: file t2.c, line 10.
gdb-peda$ c
...
gdb-peda$ b *__libc_malloc+401
Breakpoint 7 at 0x7ffff7a7b201: file malloc.c, line 2941.
gdb-peda$ c
...
3050          return tcache_get (tc_idx);
gdb-peda$ p *(tcache_perthread_struct *)$tcache_0
$7 = {
  counts = "\000\000\000\000\000\000\001", '\000' <repeats 56 times>, 
  entries = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x555555756260, 0x0 <repeats 57 times>}
}

gdb-peda$ s
...
tcache_get (tc_idx=0x6) at malloc.c:2941
2941      assert (tc_idx < TCACHE_MAX_BINS);
gdb-peda$ s
...
2943      tcache->entries[tc_idx] = e->next;
gdb-peda$ s
...
2944      --(tcache->counts[tc_idx]);
gdb-peda$ p *(tcache_perthread_struct *)$tcache_0
$8 = {
  counts = "\000\000\000\000\000\000\001", '\000' <repeats 56 times>, 
  entries = {0x0 <repeats 64 times>}
}
gdb-peda$ s
gdb-peda$ p *(tcache_perthread_struct *)$tcache_0
$9 = {
  counts = '\000' <repeats 63 times>, 
  entries = {0x0 <repeats 64 times>}
}

gdb-peda$ b *main+74
Breakpoint 8 at 0x555555554724: file t2.c, line 11.
gdb-peda$ c
gdb-peda$ p p2
$10 = (void *) 0x555555756260

释放之前的tcache分配给新的指针p2

断点说明:
b *main+61 定位到main函数第二次调用malloc的位置
[-------------------------------------code-------------------------------------]
   0x55555555470a <main+48>:    mov    rdi,rax
   0x55555555470d <main+51>:    call   0x555555554590 <free@plt>
   0x555555554712 <main+56>:    mov    edi,0x70
=> 0x555555554717 <main+61>:    call   0x5555555545b0 <malloc@plt>
   0x55555555471c <main+66>:    mov    QWORD PTR [rbp-0x8],rax
   0x555555554720 <main+70>:    mov    rax,QWORD PTR [rbp-0x8]
   0x555555554724 <main+74>:    mov    rdi,rax
   0x555555554727 <main+77>:    call   0x555555554590 <free@plt>
[------------------------------------stack-------------------------------------]

b *__libc_malloc+401 定位到tcache_get的调用位置
=> 0x7ffff7a7b201 <__GI___libc_malloc+401>: cmp    rax,0x3f
... 
Breakpoint 7, __GI___libc_malloc (bytes=0x70) at malloc.c:3050
3050          return tcache_get (tc_idx);


b *main+61 定位到第二次malloc返回的位置
=> 0x555555554724 <main+74>:    mov    rdi,rax
   0x555555554727 <main+77>:    call   0x555555554590 <free@plt>
   0x55555555472c <main+82>:    mov    eax,0x0
   0x555555554731 <main+87>:    leave  
   0x555555554732 <main+88>:    ret

参考

https://ctf-wiki.github.io/ctf-wiki/pwn/linux/glibc-heap/implementation/tcache/

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343