甄别伪代码中的常量

以下是IDA9.0生成的一段伪代码:

char aPageSFplnInitA[21] = "page_s_fpln_init.adb"; // weak

  _DWORD v44[28]; // [esp+A3D0h] [ebp-168h] BYREF

        if ( (unsigned __int8)(v11 - 32) > 0x3Au )
          __gnat_rcheck_05("page_s_fms_bite.adb", 652);
        v44[k] = *(_DWORD *)&aPageSFplnInitA[4 * v11 + 8];
 

从字面上看,上述赋值语句从一个字符串变量中取出4个字节,赋給变量v44。

但是,这不符合常理。

经分析,语句

    if ( (unsigned __int8)(v11 - 32) > 0x3Au )

实际是判断v11的值是否在值域(32,90)之中。v11用作数组的下标。

aPageSFplnInitA的起始地址是0xCC2A98.

当x11是32时,[4 * v11 + 8]=[136],0xCC2A98+136=0xCC2B20。

在汇编清单中,从.rdata:00CC2B20开始到.rdata:00CC2C0C共有236个db,实际是59个dword。

据此定义一个未被识别的数组G_CC2B20,并修改伪代码如下:

static const unsigned32 G_CC2B20[59] = {
    4,
    4,
    4,
//以下略
};

  v44[k] = G_CC2B20[v11];

以下是第二个例子:

int dword_CC2944 = 0; // weak

  for ( i = 1; i <= 12; ++i )
  {
    v3 = *((_WORD *)&dword_CC2944 + i + 1);

在以上伪代码中,dword_CC2944是一个整型数,却被用作数组。

查看汇编:

.rdata:00CC2944 dword_CC2944 dd 0
.rdata:00CC2948 _page_gps_nav_var_0 dd offset unk_1680167
.rdata:00CC294C dd offset unk_16C016B
.rdata:00CC2950 dd offset unk_16E016D
.rdata:00CC2954 dd offset unk_263016F
.rdata:00CC2958 dd offset unk_1700264
.rdata:00CC295C dd offset unk_1720171

当i为1时:

(_WORD *)&dword_CC2944 + i + 1 = 0xCC2944 + 1*2 + 1*2 = 0xCC2948

可以看出,0xCC2948是page_gps_nav_var_0的起始地址。

page_gps_nav_var_0没有在伪代码中出现,但它应该是真正要用的数组名。

数组中被标为offset的实际是2个16位的整型数,例如,unk_1680167就是0x167和0x168。

据此可修改伪代码如下:

static const unsigned16 page_gps_nav_var_0[12] =
{
  0x167, 0x168, 0x16B, 0x16C, 0x16D, 0x16E,
  0x16F, 0x263, 0x264, 0x170, 0x171, 0x172
};

  for (i = 0; i < 12; ++i) //i改为从0开始
  {
    unsigned16 v3 = page_gps_nav_var_0[i];

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值