zoukankan      html  css  js  c++  java
  • 一个Buffer Overwritten case分析笔记

    最近QA测试的时候发现在导入一个数据文件的时候会出现access violation。导入其他数据文件则没有问题。初步判断是heap corruption。

    由于QA使用的是release baseline,于是本地换成了debug baseline,这样对于debug会有帮助。

    在debug baseline上导入同样的数据文件,同样会出现问题。只不过由于是debug baseline,它会报出下面的消息:

    Heap missing last entry in committed range near 0x2fba26b8

    (你必须用windbg attach上进程,然后上述信息才会显示)

    于是,看一下heap block信息。

    0:008> !heap -x 0x2fba26b8
    HEAP 073a0000 (Seg 25400000) At 2fba29e0 Error: invalid block size

    Entry     User      Heap      Segment       Size  PrevSize  Unused    Flags
    -----------------------------------------------------------------------------
    2fba26b8  2fba26c0  073a0000  25400000       328        30         c  busy

    这个上面说一个heap block 2fba29e0的block size记录不对。

    如果你注意的话,block 2fba29e0 其实就是在2fba26b8 后面的那个block。

    2fba26b8 + 0x328 = 2fba29e0

    于是看一下2fba29e0的meta data。

    0:008> dt _HEAP_ENTRY 2fba29e0
    ntdll!_HEAP_ENTRY
       +0x000 Size             : 0
       +0x002 PreviousSize     : 0
       +0x000 SubSegmentCode   : (null)
       +0x004 SmallTagIndex    : 0xcd ''
       +0x005 Flags            : 0xcd ''
       +0x006 UnusedBytes      : 0xcd ''
       +0x007 SegmentIndex     : 0xcd ''

    heap block的meta data显然被破坏了,因为不可能分配一个0 字节的block啊

    难道是2fba26b8 的block给破坏了?

    由于是debug baseline, debug crt会使用32字节来存一些bookkeeping的信息。于是看一下。

    0:008> dt _CrtMemBlockHeader 2fba26b8+0x8 
    msvcr90d!_CrtMemBlockHeader
       +0x000 pBlockHeaderNext : 0x2fba1408 _CrtMemBlockHeader
       +0x004 pBlockHeaderPrev : 0x2fba2778 _CrtMemBlockHeader
       +0x008 szFileName       : (null)
       +0x00c nLine            : 0
       +0x010 nDataSize        : 0x88
       +0x014 nBlockUse        : 1
       +0x018 lRequest         : 13136747
       +0x01c gap              : [4]  "???"

    注意nDataSize这一行。0x88?? 0x88表示用于想分配0x88个字节的空间。

    还记得heap block meta data吗?再看一眼。


    Entry     User      Heap      Segment       Size  PrevSize  Unused    Flags
    -----------------------------------------------------------------------------
    2fba26b8  2fba26c0  073a0000  25400000       328        30         c  busy

    heap block meta data里记录了当前这个block是0x328个字节。

    heap manager和CRT 记录的不一样啊。。。。。。

    顿时陷入了无穷的困惑中。。。。。。

    这块内存究竟是多大了?

    幸好,我们还有另外一个手段。DEBUG CRT会在用户空间的前后加上一些保护字段(fdfdfdfd)标志。来看一下吧

    0:008>  dc 2fba26b8 2fba2788
    2fba26b8  00060065 0a0c0191 2fba1408 2fba2778  e........../x'./
    2fba26c8  00000000 00000000 00000088 00000001  ................
    2fba26d8  00c8736b fdfdfdfd 39c69d34 ffffffff  ks......4..9....
    2fba26e8  00000000 00000000 2f8cc200 00000000  .........../....
    2fba26f8  00000000 cdcdcdcd cdcdcdcd 00000000  ................
    2fba2708  39c66190 00000005 00000005 2fba2798  .a.9.........'./
    2fba2718  00000001 00000004 00000001 00000000  ................
    2fba2728  00000002 2fbe22a2 0000007b 00000001  ....."./{.......
    2fba2738  00000000 00000002 00000000 00000004  ................
    2fba2748  00000001 00000000 00000000 00000000  ................
    2fba2758  00000000 00000001 00000000 00000000  ................
    2fba2768  fdfdfdfd 00000000 00170008 0a0801a8  ................
    2fba2778  2fba26c0 2fba27b8 00000000 00000000  .&./.'./........
    2fba2788  00000014

    注意,从2fba26e0是用户空间起点。我们注意到,在2fba2768 有结束标志fdfdfdfd。而2fba2768-2fba26e0=0x88。

    这说明CRT的记录是正确的。那为什么heap block meta data会记录错误了?

    如果你再注意一下,在2fba2770处,应该是下一个Heap block的起点。从上面可以看出,当前这个block size应该是0x17*8 = 0xb8。而 2fba26b8+0xb8 = 2fba2770。该地址正是下一个heap block的起点。

    于是,我们可以肯定,block 2fba26b8 的meta data被别人改写了。

    一般而言,都是由于前面的block越界写了。于是,我们决定看一下前面的block是啥东东。

    0:008> dc 2fba26b8-0x30 2fba26b8
    2fba2688  00080006 0a0b0197 2fbbd3a8 30054a80  .........../.J.0
    2fba2698  00000000 00000000 00000001 00000001  ................
    2fba26a8  00c96597 fdfdfdfd 656c6554 706f6353     .e......TeleScop
    2fba26b8  00060065                                                 e...

    记住,0x30是前一个block size。所以我们减去0x30,就得到了前一个block 的起始地址。

    我们发现,前一个heap block记录了一串字符, telescope。

    但是我们发现,用户空间的前面有fdfdfdfd保护,而后面的fdfdfdfd消失了。。。

    我们再看一下crt的bookkeeping信息。

    0:008> dt _CrtMemBlockHeader 2fba2688+0x8 
    msvcr90d!_CrtMemBlockHeader
       +0x000 pBlockHeaderNext : 0x2fbbd3a8 _CrtMemBlockHeader
       +0x004 pBlockHeaderPrev : 0x30054a80 _CrtMemBlockHeader
       +0x008 szFileName       : (null)
       +0x00c nLine            : 0
       +0x010 nDataSize        : 1
       +0x014 nBlockUse        : 1
       +0x018 lRequest         : 13198743
       +0x01c gap              : [4]  "???"

    只申请了1个字节?但是却存了10个字符!!

    于是,真相大白。该处只申请了1个字节,却存了10个字符。10个字符不仅把fdfdfdfd给覆盖了,而且覆盖了下一个block的meta data的前两个字节,改写了下一个block的“block size”。

    接下来的工作就轻松许多了。我们只需要看一下数据文件里哪些地方存储了TeleScope这个字符,然后看看是怎么解析它的了。

  • 相关阅读:
    grep 和vim用法
    【python】初识函数
    【python】 文件相关操作
    【python】基础数据类型相关知识点补充和深浅拷贝
    【python】is和==的区别以及encode()和decode()
    python中的字典以及相关操作
    python列表元祖以及range
    python基本数据类型
    python基础逻辑运算
    了解Python与安装Python解释器
  • 原文地址:https://www.cnblogs.com/xiaxi/p/2059590.html
Copyright © 2011-2022 走看看