3

我有一个关于将数据(地址表或其他数据)放在.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表放在哪里?在fff功能下还是我必须把它放在.data部分?静态数据呢?例如,我有 2QWORD个函数,我必须把它放在那个函数中,或者我必须把它们QWORDs放在数据部分?为什么 ?我知道如果我把它放在 .data 部分或它的功能下没有问题,但我想知道哪种方式更好?

4

2 回答 2

4

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

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

于 2021-10-29T18:37:01.913 回答
3

是的,您可以将指针.L4:.text(您可以使用间接近跳转进行分支,该跳转从指向这些外部函数的指针表中获取目标地址。链接器负责完成外部地址。NASM/Intel 语法示例:i0i5

|                            |     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
于 2021-10-29T18:36:40.607 回答