汇编函数地址table及函数下或数据段中的数据

Assembly function address table and data under the function or in data section

我有一个问题是将数据(地址table或其他数据)放在其功能下的.text部分还是放在.data部分? 例如,我有一个这样的函数:

extern int i0();
extern int i1();
extern int i2();
extern int i3();
extern int i4();
extern int i5();

void fff(int x) {
 switch (x) {
     case 0:
     i0();
     break;
     case 1:
     i1();
     break;
     case 2:
     i2();
     break;
     case 3:
     i3();
     break;
     case 4:
     i4();
     break;
     case 5:
     i5();
     break;
 }
}

在汇编中,这是我的代码:

fff:
        cmp     edi, 5
        ja      .L10
        mov     edi, edi
        xor     eax, eax
        jmp     [QWORD PTR .L4[0+rdi*8]]
.L4:
        .quad   .L9
        .quad   .L8
        .quad   .L7
        .quad   .L6
        .quad   .L5
        .quad   .L3
.L5:
        jmp     i4
.L3:
        jmp     i5
.L9:
        jmp     i0
.L8:
        jmp     i1
.L7:
        jmp     i2
.L6:
        jmp     i3
.L10:
        ret

这里我有 .L4 保存跳转地址...我应该把这个 .L4 table 放在哪里?在 fff 函数下还是我必须将它放在 .data 部分?静态数据呢?例如,我有一个函数有 2 QWORD,我必须把它放在那个函数中,或者我必须把那些 QWORDs 放在数据部分?为什么 ?我知道放在.data段或者function下不会有问题,但是我想知道哪种方式更好?

是的,你可以把指针(.L4:)的table放在.text部分(如果它在运行时不会被修改的话)但是我没有看到双重间接指向一组外部函数跳转的原因 i0..i5。您可以使用间接近跳转进行分支,它从指向这些外部函数的 table 指针中获取目标地址。链接器负责完成外部地址。 NASM/Intel 语法示例:

|                            |     global fff
|                            |     extern i0,i1,i2,i3,i4,i5
|00000000:4883FF05           |fff: cmp rdi, 5
|00000004:773A               |     ja  .L10
|00000006:FF24FD[10000000]   |     jmp [.L4+8*rdi]
|0000000D:0F1F00             |     align 8  ; For better performance.
|00000010:[0000000000000000] |.L4: dq i0
|00000018:[0000000000000000] |     dq i1
|00000020:[0000000000000000] |     dq i2
|00000028:[0000000000000000] |     dq i3
|00000030:[0000000000000000] |     dq i4
|00000038:[0000000000000000] |     dq i5
|00000040:C3                 |.L10:ret

.data 部分通常是 writable,您不希望您的跳转 table 被意外或恶意覆盖。所以 .data 不是最好的地方。

.text 就可以了;它通常是只读的。它是否靠近功能并不重要。许多系统有一个 .rodata 部分是只读的而不是 executable,这会更好;这将有助于捕获错误或攻击,这些错误或攻击意外或故意尝试执行跳转的字节 table.