以下是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];
评论前必须登录!
注册