精简伪代码中Ada编译器增生的代码

1. Ada的变体记录 (Variant Record)

以下是IDA生成的一段伪代码:

  v7 = *(_BYTE *)a1;
  v8 = 4;
  if ( *(_BYTE *)a1 != 88 )
  {
    if ( (unsigned __int8)v7 <= 2u
      || v7 == 5
      || v7 == 7
      || v7 == 8
      || v7 == 9
      || v7 == 12
      || v7 == 13
      || v7 == 14
      || v7 == 17
      || v7 == 18
      || v7 == 15
      || v7 == 16
      || v7 == 59
      || v7 == 60
      || v7 == 61
      || v7 == 62
      || v7 == 63
      || v7 == 64
      || v7 == 65
      || v7 == 71
      || v7 == 72
      || v7 == 73
      || v7 == 74
      || v7 == 75
      || v7 == 80
      || v7 == 6
      || v7 == 81
      || v7 == 10
      || v7 == 11
      || v7 == 82
      || v7 == 51
      || v7 == 52
      || v7 == 53
      || v7 == 55
      || v7 == 58
      || v7 == 56
      || v7 == 45
      || v7 == 46
      || v7 == 47
      || v7 == 48
      || v7 == 49
      || v7 == 50
      || v7 == 92
      || v7 == 91 )
    {
      v8 = 8;
    }
    else if ( (unsigned __int8)(v7 - 39) <= 1u
           || v7 == 44
           || v7 == 41
           || v7 == 42
           || v7 == 43
           || v7 == 38
           || v7 == 85
           || v7 == 86
           || v7 == 87
           || v7 == 89
           || v7 == 90 )
    {
      v8 = 8;
    }
    else if ( v7 == 3
           || v7 == 19
           || v7 == 20
           || v7 == 21
           || v7 == 22
           || v7 == 23
           || v7 == 24
           || v7 == 25
           || v7 == 26
           || v7 == 27
           || v7 == 28
           || v7 == 29
           || v7 == 30
           || v7 == 31
           || v7 == 32
           || v7 == 33
           || v7 == 34
           || v7 == 35
           || v7 == 36
           || v7 == 37
           || v7 == 67
           || v7 == 68
           || v7 == 66
           || v7 == 69
           || v7 == 70 )
    {
      v8 = 104;
    }
    else
    {
      v8 = 8 * (v7 == 4) + 8;
    }
  }
  v9 = v17;
  v10 = v8;
  qmemcpy(v17, v15, 4 * (v8 >> 2));
  v12 = &v15[4 * (v8 >> 2)];
  v11 = &v9[4 * (v8 >> 2)];
  v13 = v8 & 2;
  if ( v13 )
  {
    LOWORD(v13) = *(_WORD *)v12;
    *(_WORD *)v11 = *(_WORD *)v12;
    v11 += 2;
    v12 += 2;
  }
  if ( (v10 & 1) != 0 )
  {
    LOBYTE(v13) = *v12;
    *v11 = *v12;
  }

这段代码的核心功能是:qmemcpy(v17, v15, 4 * (v8 >> 2));

根据上下文,v17与v15是两个变体记录类型的变量。

Ada语言中的变体记录的特点是,它的一些成员存在与否取决于该记录的参数。例如:

type Gender is (Male, Female);
type Person (Sex : Gender)is
   record
      Birth : Date;
      case Sex is
         when Male =>
            Bearded : Boolean;
         when Female =>
            Children : Integer;
      end case;
   end record;

上例中,case Sex ... end case 即是变体部份。

笔者用C语言的联合类型来替代变体记录。这样,在C代码中,v17与v15的所有成员都是静态定义的,不需要动态地计算v15的长度。

因此,上述伪代码可改写为一行C代码:17 = v15;

2. Ada语言的范围检查

以下是IDA生成的一段伪代码:

上述代码中的函数mmi_server_types__t_result_data_fm_commandD116是Ada编译器生成的,用于检查变体记录类型的变量中所用的参数是否合法。

同样的调用出现了5次。在有些地方,甚至连续出现几十次。

为了便于阅读,笔者写了一个小工具,根据作用域来删除这类重复的调用语句。

3. 结语

从以上两个例子,可以领略Ada语言的灵活和严谨。

由于笔者的目的是为了学习原始代码中的设计思想,所以在把伪代码转化为C代码时精简了Ada编译器增生的代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值