本文的操作内存函数是指memcpy和memset这两个函数。
以下是IDA生成的伪代码中的一个memcpy例子:
_WORD v5[272]; // [esp+18h] [ebp-298h] BYREF
memcpy(v5, mmi_application_types__c_nul_array_parameters, 0x21Cu);
经分析,mmi_application_types__c_nul_array_parameters是一个结构体数组,其定义应修改如下:
typedef struct
{
unsigned16 _0;//page_data_element_t
mmi_application_types__data_format_t _4;
} mmi_application_types__parameters_t;//max size=108
mmi_application_types__parameters_t mmi_application_types__c_nul_array_parameters[5];
结构体类型mmi_application_types__parameters_t是笔者的逆向分析结果。如果按这个结构体类型编译从伪代码改造过来的C代码,其尺寸不一定仍然是原始的108个字节,从而整个结构体数组的尺寸也不一定仍然是540(0x21C)个字节。
因此,上述伪代码要修改为:
mmi_application_types__parameters_t v5[5];
memcpy(v5,
mmi_application_types__c_nul_array_parameters,
sizeof(mmi_application_types__c_nul_array_parameters));
总之,memcpy的第3个实参不能用常数,而是要改为sizeof(<变量名>|<类型名>)。
对于memset的第3个实参也要执行这样的修改规则。
以下是另一种例子:
char aFix1_7[11] = "FIX1 "; // weak
memcpy(&unk_28AADEC, aFix1_7, 0x7Cu);
经分析,aFix1_7不是字符串变量,而是一个结构体常量。它的起始地址是0xC681FC。字符串"FIX1 "只是它的第一个分量。
因此,把aFix1_7改名为G_C681FC,并重新定义该常量的数据内容。
变量unk_28AADEC实际是某个结构体数组的成员。因此,这行memcpy调用语句可改为两个变量之间的赋值语句。
static const mcdu_fixed_line_124_t G_C681FC = {
"FIX1 ",
{
{16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16
},
0x18,
},
1, 10, 0
};
page_s_fpln_init__c_fix_areas[1] = G_C681FC;
Ada语言中没有memcpy函数,改为赋值语句应该算是尽量恢复原状吧。