Ada数组下标为枚举变量时的逆向分析

Ada语言允许把枚举变量作为数组的下标。例如:

   type DAY is (MON, TUE, WED, THU, FRI, SAT, SUN);

   Hours : array (DAY) of Float;

对于上述这类程序的目标码,手头的IDA产生了奇怪的伪代码。例如:

_UNKNOWN *jpt_721AB2[77] =
{
  &loc_721B39,
  &loc_721B39,
  &loc_721B39,
  &loc_721B39,
  &loc_721B39,
  &def_7218B8,
  &def_7218B8,
  &def_7218B8,
  &def_7218B8,
  &def_7218B8,
  &def_7218B8,
  &def_7218B8,
  &def_7218B8,
  &def_7218B8,
  &def_7218B8,
  &def_7218B8,
  &def_7218B8,
  &def_7218B8,
  &def_7218B8,
  &loc_721B39,
  &loc_721B39,
  &loc_721B39,
  &loc_721B39,
  &def_7218B8,
  &loc_721C96,
  &def_7218B8,
  &loc_721C01,
  &def_7218B8,
  &def_7218B8,
  &def_7218B8,
  &loc_721AF4,
  &loc_721B18,
  &loc_721B53,
  &def_7218B8,
  &loc_721B39,
  &def_7218B8,
  &def_7218B8,
  &def_7218B8,
  &def_7218B8,
  &def_7218B8,
  &def_7218B8,
  &loc_721B39,
  &def_7218B8,
  &def_7218B8,
  &def_7218B8,
  &def_7218B8,
  &loc_721B39,
  &def_7218B8,
  &def_7218B8,
  &loc_721B53,
  &def_7218B8,
  &def_7218B8,
  &loc_721B53,
  &loc_721B53,
  &def_7218B8,
  &loc_721B53,
  &def_7218B8,
  &def_7218B8,
  &def_7218B8,
  &def_7218B8,
  &def_7218B8,
  &def_7218B8,
  &def_7218B8,
  &loc_721AB9,
  &def_7218B8,
  &def_7218B8,
  &loc_721B53,
  &loc_721ADA,
  &loc_721BC7,
  &loc_721BC7,
  &loc_721BC7,
  &def_7218B8,
  &loc_721B53,
  &loc_721B53,
  &loc_721B53,
  &def_7218B8,
  &def_7218B8
}; // weak


v2 = BYTE2(jpt_721AB2[2 * a2 + 76]);

只好查看对应的汇编代码:

.text:007A71B7 mov     cl, byte ptr ds:off_CC175C+132h[eax*8]

此时eax的值是该函数的输入参数a2。

查看该函数的所有调用语句,发现a2的实参分别是:914,915,916,917,919,920,921。

当eax为914时,ds:off_CC175C+132h[eax*8]对应的地址值是:

0xCC175C+0x132+914*8=0xCC351E=0x0xCC351C+2

在汇编代码清单中有:

.rdata:00CC351C _lists_manager__c_caract_list db  92h
.rdata:00CC351D db    3
.rdata:00CC351E db  1Ah
.rdata:00CC351F db    0
.rdata:00CC3520 db    2
.rdata:00CC3521 db    0
.rdata:00CC3522 db    0
.rdata:00CC3523 db    0
.rdata:00CC3524 db  93h
.rdata:00CC3525 db    3
.rdata:00CC3526 db  21h ; !
.rdata:00CC3527 db    0
.rdata:00CC3528 db    3

;以下略

由此可知,语句”v2 = BYTE2(jpt_721AB2[2 * a2 + 76]);“要访问的是全局变量lists_manager__c_caract_list。而这个全局变量在伪代码中没有出现过。

经分析,lists_manager__c_caract_list可定义为以下C语言的结构数组:

typedef struct
{
  unsigned16 _0;
  unsigned8 _2;
  unsigned8 _4;
  unsigned8 _6;
} lists_manager__c_caract_list_t;

static lists_manager__c_caract_list_t lists_manager__c_caract_list[11] =
{
  {0x392, 0x1A, 2, 0},
  {0x393, 0x21, 3, 0},
  {0x394, 0x19, 3, 0},
  {0x395, 0x21, 2, 0},
  {0x399, 0x1C, 1, 0},
  {0x397, 0x25, 1, 0},
  {0x398, 0x15, 3, 0},
  {0x399, 0x1C, 1, 0},
  {0x39A, 0x15, 1, 0},
  {0x39B, 0x19, 3, 0},
  {0x39C, 0x21, 0x0F, 0},
};

伪代码语句:

      v2 = BYTE2(jpt_721AB2[2 * a2 + 76]);

可改为C语句:

     v2 = lists_manager__c_caract_list[a2 - 914]._2;

a2是数组下标,减去914后就变成了C程序的数组下标,其取值范围是0..10。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值