有以下示例代码:

void main()
{
    char buf[45] = {0x52,0x49,0x46,0x46,0x24,0x00,0x00,0x80,0x57,0x41,0x56,0x45,0x66,0x6d,0x74,0x20,0x10,0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x44,0xac,0x00,0x00,0x10,0xb1,0x02,0x00,0x04,0x00,0x10,0x00,0x64,0x61,0x74,0x61,0x00,0x00,0x00,0x80};
}

通过montavista的编译器(gcc version 4.4.1 (MontaVista Linux G++ 4.4-1302012138)),不带优化编出来的二进制文件中,数组存在于代码段(.text):

52 30 A0 E3 34 30 4B E5 49 30 A0 E3 33 30 4B E5 46 30 A0 E3 32 30 4B E5 46 30 A0 E3 31 30 4B E5 24 30 A0 E3 30 30 4B E5 7F 30 E0 E3 2D 30 4B E5 57 30 A0 E3 2C 30 4B E5 41 30 A0 E3 2B 30 4B E5 56 30 A0 E3 2A 30 4B E5 45 30 A0 E3 29 30 4B E5 66 30 A0 E3 28 30 4B E5 6D 30 A0 E3 27 30 4B E5 74 30 A0 E3 26 30 4B E5 20 30 A0 E3 25 30 4B E5 10 30 A0 E3 24 30 4B E5 01 30 A0 E3 20 30 4B E5 02 30 A0 E3 1E 30 4B E5 44 30 A0 E3 1C 30 4B E5 53 30 E0 E3 1B 30 4B E5 10 30 A0 E3 18 30 4B E5 4E 30 E0 E3 17 30 4B E5 02 30 A0 E3 16 30 4B E5 04 30 A0 E3 14 30 4B E5 10 30 A0 E3 12 30 4B E5 64 30 A0 E3 10 30 4B E5 61 30 A0 E3 0F 30 4B E5 74 30 A0 E3 0E 30 4B E5 61 30 A0 E3 0D 30 4B E5 7F 30 E0 E3 09 30 4B E5

我希望修改的是数组中的第24,25位: 0x44, 0xac -> 0x80 0xbb.

通过观察可以发现:

  1. 0x00不会保存在ELF文件中
  2. 如果最高位是0,例如第七个字节0x80,在ELF文件中就是保存其反码:0x7F
  3. 每个数字后面会有7个字节的信息数据,其中:
    • 第二个字节可能是0xA0(代表数据保存为原码),也可能是0xE0(代表数据保存为反码);
    • 第四个字节是每次递减的一个数字,正常情况下一次递减1;特别地,如果中间有N个0数据,则递减N

因此应该将相应部分改成0x7f 0x44,并且把0x7f后面的第2个字节从0xA0改为0xE0.