关于各种free错误的定位方法
Posted rec0rd
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于各种free错误的定位方法相关的知识,希望对你有一定的参考价值。
前言:glibc在free一块堆内存的时候会检查堆头,如果堆头有异常,就报free err、double free等问题,然而实际上这可能是另外一个地方的堆溢出导致的本堆块堆头被踩导致的,并不是什么double free。这个时候就有个简单的定位方法去定位这种问题。
1. 现象:
Continuing.
*** glibc detected *** ...: double free or corruption (out): 0x0000000000627f90 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x76628)[0x7ffff720b628]
/lib64/libc.so.6(cfree+0x6c)[0x7ffff72105cc]
...
======= Memory map: ========
...
0061c000-00682000 rw-p 00000000 00:00 0 [heap]
7ffff0000000-7ffff0021000 rw-p 00000000 00:00 0
7ffff0021000-7ffff4000000 ---p 00000000 00:00 0
7ffff6d67000-7ffff6d7d000 r-xp 00000000 08:07 803123 /usr/local/lib64/libgcc_s.so.1
2. 定位方法:
gdb拉入目标程序,先在free上下断点,制作command另其自动打印调用栈、自动继续,这样我们可以看到glibc报错时候的调用栈:
b free
command 1
>silent
>bt
>c
>end
运行crash样本,发现free出错点和释放出错的堆结构体:
(gdb) bt
#0 0x00007ffff7210560 in free () from /lib64/libc.so.6
#1 0x00000000004140c0 in av_free (ptr=<optimized out>) at libavutil/mem.c:282
#2 av_freep ([email protected]=0x61d178) at libavutil/mem.c:289
#3 0x00000000004048c1 in hevc_decode_free (avctx=<optimized out>) at libavcodec/hevc.c:3281
#4 0x00000000004137ad in avcodec_close (avctx=0x61cbf0) at libavcodec/utils.c:106
#5 0x0000000000402ba7 in hevc_decode_end ([email protected]=0x61c010) at libbpg.c:564
#6 0x0000000000403edc in bpg_decoder_decode ([email protected]=0x61c010, [email protected]=0x61c250 "BPG\373 ", [email protected]=2450) at libbpg.c:1882
#7 0x0000000000401410 in main (argc=<optimized out>, argv=<optimized out>) at bpgdec.c:332
*** glibc detected *** ...: double free or corruption (out): 0x0000000000627f90 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x76628)[0x7ffff720b628]
/lib64/libc.so.6(cfree+0x6c)[0x7ffff72105cc]
源码定位到该结构体申请时的代码,下断点并重新运行crash样本,在断点处获取到该结构体的内存地址addr(此处malloc返回的地址为0x627f90),然后在addr-16地址下硬件断点(为了检测堆头被破坏的过程):
(gdb) watch *0x627f90 - 16
Hardware watchpoint 8: *0x627f88
(gdb) c
Continuing.
Hardware watchpoint 8: *0x627f88
Old value = 209
New value = 0
restore_tqb_pixels ([email protected]=0x61d050, [email protected]=0x64b010 "M", [email protected]=0x63a7c6 "M", stride_src=256, stride_dst=132, x0=<optimized out>, y0=192, width=64, height=64, c_idx=0) at libavcodec/hevc_filter.c:228
228 memcpy(src, dst, len);
(gdb)
3. 成功抓到罪魁祸首:堆溢出。
以上是关于关于各种free错误的定位方法的主要内容,如果未能解决你的问题,请参考以下文章
Appium基于安卓的各种FindElement的控件定位方法实践和建议
selenium使用Xpath+CSS+JavaScript+jQuery的定位方法(治疗selenium各种定位不到,点击不了的并发症)