反汇编代码分析之CVE-2012-0774

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/counsellor/article/details/84863593

0x00 序言

最近在看CVE-2012-0774这个洞,其中一个函数的反汇编是这样的,看上去有点懵逼,知道逻辑不难,就是无从下手。

0x01 源码

在IDA中看函数 sub_800798B 只有一处上层引用
在这里插入图片描述
具体源码如下

int __cdecl sub_800798B(int a1)
{
  unsigned int v1; // edi@2
  _DWORD *v2; // eax@3
  int v3; // edx@3
  unsigned int v4; // ecx@3
  int v5; // edi@5
  int result; // eax@8

  if ( (unsigned int)(dword_82323E0 - 4) < *(_DWORD *)dword_82323EC
    || (v1 = *(_DWORD *)(dword_82323EC + 340), dword_82323E0 - 4 >= v1)
    || (v2 = (_DWORD *)(dword_82323E0 - 4),
        v3 = *(_DWORD *)(dword_82323E0 - 4),
        v4 = dword_82323E0 - 4 - 4 * *(_DWORD *)(dword_82323E0 - 4),
        v4 < *(_DWORD *)dword_82323EC)
    || v4 >= v1 ) 
  {
    result = dword_8232438;
    dword_8232434 = 4368;
  }
  else
  {
    v5 = *(_DWORD *)v4;
    if ( v3 > 0 )
    {
      do
      {
        --v3;
        *(_DWORD *)v4 = *(_DWORD *)(v4 + 4);
        v4 += 4;
      }
      while ( v3 );
      --v2;
    }
    *v2 = v5;
    dword_82323E0 = (int)(v2 + 1);
    result = a1;
  }
  return result;
}

0x02 问题

  1. 参数a1没有参与运算,直接赋值给result,正常漏洞出发都是有输入参与运算的,莫非这里不是关键函数?
  2. if语句中有多个表达式用逗号分开构成,那一句才是真值的判断条件?
  3. dword_82323E0表示什么?dword_82323EC又表示什么?
  4. 这个函数的功能是什么?

0x03 分析

int __cdecl sub_800798B(int a1)
{
  unsigned int v1; // edi@2 局部变量
  _DWORD *v2; // eax@3 局部变量
  int v3; // edx@3 局部变量
  unsigned int v4; // ecx@3 局部变量
  int v5; // edi@5  局部变量
  int result; // eax@8 用来保存处理结果,并返回

  if ( (unsigned int)(dword_82323E0 - 4) < *(_DWORD *)dword_82323EC //*dword_82323EC是一个下界
    || (v1 = *(_DWORD *)(dword_82323EC + 340), //*(dword_82323EC+340)是一个上界
    	dword_82323E0 - 4 >= v1) //如果看出哪个是上界,哪个是下界?
    || (v2 = (_DWORD *)(dword_82323E0 - 4), //正常c语言不允许多个语句,这里其实是个长语句切开了
        v3 = *(_DWORD *)(dword_82323E0 - 4), //v3后面没有在if中用到,说明编译器编译时乱序了(陷阱[1])
        v4 = dword_82323E0 - 4 - 4 * *(_DWORD *)(dword_82323E0 - 4), //v4是一个关键数组值地址
        v4 < *(_DWORD *)dword_82323EC) //v4如果小于下界则直接return 一个值,不进行逻辑运算
    || v4 >= v1 ) // v4如果大于上界也会return 4368,不进行逻辑运算
  {
    result = dword_8232438; //有点像错误的标记,被作为result返回
    dword_8232434 = 4368;
  }
  else
  {
    v5 = *(_DWORD *)v4; //v5是v4地址保存的值
    if ( v3 > 0 ) //向后看,v3>0 && v3不断自减,说明v3是个计数器,同时也来自dword_82323E0这个数组
    {
      do
      {
        --v3; //计数器自减
        *(_DWORD *)v4 = *(_DWORD *)(v4 + 4); //v4的下一个值移动到v4
        v4 += 4; //v4指向的地址向后移动1个索引位置,初步断定数据存的是4个字节数据,所以addr+4就是索引+1
      }
      while ( v3 );  
      --v2; //这里是个陷阱[2],因为v2与v4都是dword_82323E0数组中的地址,而v2做-1操作,和v4做+4操作的移动步长相悖
    }
    *v2 = v5; //v4的值在循环中被v4的下个值冲掉了,v5在循环前保存了v4的值,这里赋值给v2
    // 整体逻辑基本结束,推断如下:
    //该函数把某数组的值整体前移,并把第一个值追加到末尾。
    //即数据循环左移一位操作
    dword_82323E0 = (int)(v2 + 1); //dword_82323E0指向数组末尾的下一位
    result = a1; //返回a1
  }
  return result;
}

按照阅读代码的顺序,初步分析已经结束。
总结下新产生的问题:

5. 如何断定这个大if语句是边界检查?
6. 陷阱[1] v3只在后面用到一次,且表示计数器吗?
7. 陷阱[2] --v2表示地址-1的操作为什么跟v4 + 4的逻辑不通,不在一个维度吗?命名都是由dword_82323E0这个地址产生的。

回答问题:

  1. 有些输入数据是存在全局变量中,不使用传参以可以访问poc数据;
  2. 多个语句其实是把c中的一个复杂语句拆开了,其中的赋值语句只是用来存临时变量的,没有实际的条件意义;
  3. dword_82323E0是用dword_为前缀的变量,这个变量是32位长度,4字节,可能是可能是指针地址,可能是数值。根据函数上下文判断,这个变量表示参与计算可变数组地址。dword_82323EC表示数组下界,即数组首地址,dword_82323EC + 340表示数据的上界;
  4. 该函数完成了以dword_82323E0为上界,v3为size的数组循环左移一位的功能,注意上界是数组结束的位置。 dword_82323E0-v3才是首地址
  5. 一般导致函数直接返回的条件是错误条件,同时if中只有在某段闭区间才能执行后面的逻辑,所以很容易确定这个是边界检查
  6. v3其实在if中用到了,只是没有用v3替换,它是需要操作数组的size,这是一个隐含信息。

在这里插入图片描述

  1. v2跟v4一样是数组的指针,只不过,v2是4字节指针(_DWORD *),v4是4字节整数,指针自增1,其实也是地址向后移动了4个字节,基本原理:*(addr+4)与*(addr)+1是等价关系。可以回顾下“数组名取地址”的基本知识

0x04 流程图

如下图,v3=3,或者说size=3。 把第一个元素e3移动到末尾,其他元素左移1位
在这里插入图片描述

我想说这个图其实有点诡异,为什么不是横着放,而且这个数组明显是4个元素,怎么size是3?

需要提醒的是v3是从数据区里取出来的,在边界检查时,也可以看到,v3的数值在【*(_DWORD *)dword_82323EC, *(_DWORD *)(dword_82323EC+340】范围之间,v3极大可能是小于正常数据大小的。所以sub_800798B函数与该图像符合。

揭秘
该图是一个栈,size=3弹栈后,作为参数,控制栈的变化。
具体解释可以参考微软opentype字体使用文档的MINDEX指令【传送门

0x05 小结

  1. _DWORD与*的组合博大精深,什么_DWORD *v2,什么(_DWORD )(dword_82323E0 - 4),什么(_DWORD *)(dword_82323E0 - 4),什么 4 * *(_DWORD *)(dword_82323E0 - 4)很容易搞死人,但是反复推敲之后总能明白。
  2. 本文开始忽略了陷阱问题,本来很简单的逻辑,怎么也解释不通。要多思考。

0x06 参考文献

https://docs.microsoft.com/en-us/typography/opentype/spec/tt_instructions
https://www.cnblogs.com/yxysuanfa/p/7352619.html

猜你喜欢

转载自blog.csdn.net/counsellor/article/details/84863593