云计算百科
云计算领域专业知识百科平台

甄别伪代码中的常量

以下是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];

赞(0)
未经允许不得转载:网硕互联帮助中心 » 甄别伪代码中的常量
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!